<?php
/**
 * ---------------------------------------------------------------------
 * GLPI - Gestionnaire Libre de Parc Informatique
 * Copyright (C) 2015-2018 Teclib' and contributors.
 *
 * http://glpi-project.org
 *
 * based on GLPI - Gestionnaire Libre de Parc Informatique
 * Copyright (C) 2003-2014 by the INDEPNET Development Team.
 *
 * ---------------------------------------------------------------------
 *
 * LICENSE
 *
 * This file is part of GLPI.
 *
 * GLPI is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * GLPI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GLPI. If not, see <http://www.gnu.org/licenses/>.
 * ---------------------------------------------------------------------
 */

/**
 * Update from 0.84 to 0.85
 *
 * @return bool for success (will die for most error)
**/
function update084to085() {
   global $DB, $migration;

   $updateresult       = true;
   $ADDTODISPLAYPREF   = [];
   $DELFROMDISPLAYPREF = [];

   //TRANS: %s is the number of new version
   $migration->displayTitle(sprintf(__('Update to %s'), '0.85'));
   $migration->setVersion('0.85');

   $backup_tables = false;
   $newtables     = ['glpi_blacklistedmailcontents',
                          'glpi_changecosts', 'glpi_changes', 'glpi_changes_groups',
                          'glpi_changes_items', 'glpi_changes_problems', 'glpi_changes_projects',
                          'glpi_changes_suppliers', 'glpi_changes_tickets', 'glpi_changes_users',
                          'glpi_changetasks', 'glpi_changevalidations',
                          'glpi_dropdowntranslations',
                          'glpi_knowbaseitemtranslations',
                          'glpi_notepads',
                          'glpi_problemcosts', 'glpi_projectcosts',
                          'glpi_projects', 'glpi_projects_changes', 'glpi_projects_items',
                          'glpi_projectstates', 'glpi_projecttasks', 'glpi_projecttasks_tickets',
                          'glpi_projecttaskteams', 'glpi_projecttasktypes',
                          'glpi_projectteams', 'glpi_projecttypes',
                          'glpi_queuedmails'
                          // Only do profilerights once : so not delete it
                          /*, 'glpi_profilerights'*/];

   foreach ($newtables as $new_table) {
      // rename new tables if exists ?
      if ($DB->tableExists($new_table)) {
         $migration->dropTable("backup_$new_table");
         $migration->displayWarning("$new_table table already exists. ".
                                    "A backup have been done to backup_$new_table.");
         $backup_tables = true;
         $query         = $migration->renameTable("$new_table", "backup_$new_table");
      }
   }
   if ($backup_tables) {
      $migration->displayWarning("You can delete backup tables if you have no need of them.",
                                 true);
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'config table'));

   if ($DB->fieldExists('glpi_configs', 'version')) {
      if (!$DB->tableExists('origin_glpi_configs')) {
         $migration->copyTable('glpi_configs', 'origin_glpi_configs');
      }

      $configIterator = $DB->request([
         'FROM'   => "glpi_configs",
         'WHERE'  => [
            'id' => 1
         ]
      ]);

      // Update glpi_configs
      $migration->addField('glpi_configs', 'context', 'VARCHAR(150) COLLATE utf8_unicode_ci',
                           ['update' => 'core']);
      $migration->addField('glpi_configs', 'name', 'VARCHAR(150) COLLATE utf8_unicode_ci',
                           ['update' => 'version']);
      $migration->addField('glpi_configs', 'value', 'text', ['update' => '0.85']);
      $migration->addKey('glpi_configs', ['context', 'name'], 'unicity', 'UNIQUE');

      $migration->migrationOneTable('glpi_configs');

      if (count($configIterator) === 1) {
         $configs = $configIterator->next();
         unset($configs['id']);
         unset($configs['version']);
         // First drop fields not to have constraint on insert
         foreach ($configs as $name => $value) {
            $migration->dropField('glpi_configs', $name);
         }
         $migration->migrationOneTable('glpi_configs');
         // Then insert new values
         foreach ($configs as $name => $value) {
            $DB->insert("glpi_configs", [
               'context'   => "core",
               'name'      => $name,
               'value'     => $value,
            ]);
         }
      }
      $migration->dropField('glpi_configs', 'version');
      $migration->migrationOneTable('glpi_configs');
      $migration->dropTable('origin_glpi_configs');

   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'profile table'));

   if (!$DB->tableExists('glpi_profilerights')) {
      if (!$DB->tableExists('origin_glpi_profiles')) {
         $migration->copyTable('glpi_profiles', 'origin_glpi_profiles');
      }

      $query = "CREATE TABLE `glpi_profilerights` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `profiles_id` int(11) NOT NULL DEFAULT '0',
                  `name` varchar(255) DEFAULT NULL,
                  `rights` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`profiles_id`, `name`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_profilerights");

      $query = "DESCRIBE `origin_glpi_profiles`";

      $rights = [];
      foreach ($DB->request($query) as $field) {
         if ($field['Type'] == 'char(1)') {
            $rights[$field['Field']] = $field['Field'];
            $migration->dropField('glpi_profiles', $field['Field']);
         }
      }
      $query = "origin_glpi_profiles";

      foreach ($DB->request($query) as $profile) {
         $profiles_id = $profile['id'];

         foreach ($rights as $right) {
            $new_right = 0;

            if (($profile[$right] == 'r')
                || ($profile[$right] == '1')) {
               $new_right = READ;
            } else if ($profile[$right] == 'w') {
               $new_right = ALLSTANDARDRIGHT;
            }

            $DB->insert("glpi_profilerights", [
               'profiles_id'  => $profiles_id,
               'name'         => $right,
               'rights'       => $new_right
            ]);
         }
      }
      $migration->migrationOneTable('glpi_profiles');
      $migration->dropTable('origin_glpi_profiles');
   }

   // New system of profiles

   // delete import_externalauth_users
   $profileRightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         "name"      => "import_externalauth_users",
         "rights"    => ALLSTANDARDRIGHT
      ]
   ]);
   foreach ($profileRightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . User::IMPORTEXTAUTHUSERS
            ),
         ], [
            'profiles_id'  => $profrights['profiles_id'],
            'name'         => "user",
         ],
         "0.85 update user with import_externalauth_users right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => 'import_externalauth_users'
      ],
      "0.85 delete import_externalauth_users right"
   );

   // save value of rule_ticket to root_rule_ticket
   $DB->updateOrDie("glpi_profilerights", [
         'name' => "root_rule_ticket",
      ], [
         'name' => "rule_ticket"
      ],
      "0.85 rename rule_ticket to root_rule_ticket"
   );

   // rename entity_rule_ticket to rule_ticket
   $DB->updateOrDie("glpi_profilerights", [
         'name' => "rule_ticket",
      ], [
         'name' => "entity_rule_ticket"
      ],
      "0.85 rename entity_rule_ticket to rule_ticket"
   );

   // delete root_rule_ticket
   $profilerightsIterator = $DB->request([
      'FROM' => "glpi_profilerights",
      'WHERE' => [
         'name' => "root_rule_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . RuleTicket::PARENT
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "rule_ticket"
         ],
         "0.85 update new rule_ticket with old rule_ticket right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => "root_rule_ticket"
      ],
      "0.85 delete old rule_ticket right"
   );

   // delete knowbase_admin
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "knowbase_admin",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . KnowbaseItem::KNOWBASEADMIN
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "knowbase"
         ],
         "0.85 update knowbase with knowbase_admin right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => "knowbase_admin"
      ],
      "0.85 delete knowbase_admin right"
   );

   // delete faq
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "faq",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . KnowbaseItem::READFAQ
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "knowbase"
         ],
         "0.85 update knowbase with read faq right"
      );
   }

   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "faq",
         'rights' => ALLSTANDARDRIGHT
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . KnowbaseItem::READFAQ . " | " .
               KnowbaseItem::PUBLISHFAQ
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "knowbase"
         ],
         "0.85 update knowbase with write faq right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => "faq"
      ],
      "0.85 delete faq right"
   );

   // delete user_authtype
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "user_authtype",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . User::READAUTHENT
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "user"
         ],
         "0.85 update user with read user_authtype right"
      );
   }

   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "user_authtype",
         'rights' => ALLSTANDARDRIGHT
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . User::READAUTHENT . " | ". User::UPDATEAUTHENT
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "user"
         ],
         "0.85 update user with write user_authtype right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => "user_authtype"
      ],
      "0.85 delete user_authtype right"
   );

   // delete entity_helpdesk
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "entity_helpdesk",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Entity::READHELPDESK
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "entity"
         ],
         "0.85 update entity with read entity_helpdesk right"
      );
   }

   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "entity_helpdesk",
         'rights' => ALLSTANDARDRIGHT
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
         $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Entity::READHELPDESK . " | " .
               Entity::UPDATEHELPDESK
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "entity"
         ],
         "0.85 update user with write entity_helpdesk right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => "entity_helpdesk"
      ],
      "0.85 delete entity_helpdesk right"
   );

   // delete reservation_helpdesk
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "reservation_helpdesk",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . ReservationItem::RESERVEANITEM
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "reservation_central"
         ],
         "0.85 update reservation_central with reservation_helpdesk right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights", [
         'name' => "reservation_helpdesk"
      ],
      "0.85 delete reservation_helpdesk right"
   );

   // rename reservation_central
   $DB->updateOrDie("glpi_profilerights",
      ['name' => "reservation"],
      ['name' => 'reservation_central'],
      "0.85 delete reservation_central"
   );

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'ticket']) == 0) {
      // rename create_ticket
      $DB->updateOrDie("glpi_profilerights",
         ['name' => "ticket"],
         ['name' => 'create_ticket'],
         "0.85 rename create_ticket to ticket"
      );

      $DB->updateOrDie("glpi_profilerights", [
         'rights' => (CREATE | Ticket::READMY)
         ], [
            'name' => 'ticket',
            'rights' => 1
         ],
         "0.85 update ticket with create_ticket right"
      );
   }

   // delete update_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "update_ticket",
         'rights' => 1
      ]
   ]);

   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression($DB->quoteName("rights") . " | " . UPDATE)
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with update_ticket right"
      );
   }

   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "update_ticket"],
      "0.85 delete update_ticket right"
   );

   // delete delete_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "delete_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . DELETE . " | " . PURGE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with delete_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "delete_ticket"],
      "0.85 delete delete_ticket right"
   );

   // delete show_all_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_all_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::READALL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with show_all_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_all_ticket"],
      "0.85 delete show_all_ticket right"
   );

   // delete show_group_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_group_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::READGROUP
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with show_group_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_group_ticket"],
      "0.85 delete show_group_ticket right"
   );

   // delete show_assign_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_assign_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::READASSIGN
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with show_assign_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_assign_ticket"],
      "0.85 delete show_assign_ticket right"
   );

   // delete assign_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "assign_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::ASSIGN
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with assign_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "assign_ticket"],
      "0.85 delete assign_ticket right"
   );

   // delete steal_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "steal_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::STEAL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with steal_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "steal_ticket"],
      "0.85 delete steal_ticket right"
   );

   // delete own_ticket
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "own_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::OWN
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with own_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "own_ticket"],
      "0.85 delete own_ticket right"
   );

   // delete update_priority
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "update_priority",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Ticket::CHANGEPRIORITY
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticket"
         ],
         "0.85 update ticket with update_priority right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "update_priority"],
      "0.85 delete update_priority right"
   );

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'followup']) == 0) {
      // rename create_ticket
      $DB->updateOrDie("glpi_profilerights",
         ['name' => "followup"],
         ['name' => 'global_add_followups'],
         "0.85 rename global_add_followups to followup"
      );

      $DB->updateOrDie("glpi_profilerights", [
         'rights' => ITILFollowup::ADDALLTICKET
         ], [
            'name' => 'followup',
            'rights' => 1
         ],
         "0.85 update followup with global_add_followups right"
      );
   }

   // delete add_followups
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "add_followups",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . ITILFollowup::ADDMYTICKET
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with add_followups right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "add_followups"],
      "0.85 delete add_followups right"
   );

   // delete group_add_followups
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "group_add_followups",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . ITILFollowup::ADDGROUPTICKET
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with group_add_followups right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "group_add_followups"],
      "0.85 delete group_add_followups right"
   );

   // delete observe_ticket for followup
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "observe_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . ITILFollowup::SEEPUBLIC
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with observe_ticket right"
      );
   }
    // don't delete observe_ticket because already use for task

   // delete show_full_ticket for followup
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_full_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . ITILFollowup::SEEPUBLIC . " | " .
               ITILFollowup::SEEPRIVATE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with show_full_ticket right"
      );
   }
   // don't delete show_full_ticket because already use for task

   // delete update_followups
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "update_followups",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . READ . " | " . ITILFollowup::UPDATEALL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with update_followups right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "update_followups"],
      "0.85 delete update_followups right"
   );

   // delete update_own_followups
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "update_own_followups",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . READ . " | " . ITILFollowup::UPDATEMY
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with update_own_followups right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "update_own_followups"],
      "0.85 delete update_own_followups right"
   );

   // delete delete_followups
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "delete_followups",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . PURGE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "followup"
         ],
         "0.85 update followup with delete_followups right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "delete_followups"],
      "0.85 delete delete_followups right"
   );

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'task']) == 0) {
      // rename create_ticket
      $DB->updateOrDie("glpi_profilerights",
         ['name' => 'task' ],
         ['name' => 'global_add_tasks'],
         "0.85 rename global_add_tasks to task"
      );

      $DB->updateOrDie("glpi_profilerights", [
            'rights' => CommonITILTask::ADDALLITEM
         ], [
            'name' => 'task',
            'rights' => 1
         ],
         "0.85 update followup with global_add_tasks right"
      );
   }

   // delete update_tasks
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "update_tasks",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . READ . " | " . TicketTask::UPDATEALL  .
               " | " . PURGE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "task"
         ],
         "0.85 update task with update_tasks right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "update_tasks"],
      "0.85 delete update_tasks right"
   );

   // delete observe_ticket for task
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "observe_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . TicketTask::SEEPUBLIC
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "task"
         ],
         "0.85 update task with observe_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "observe_ticket"],
      "0.85 delete observe_ticket right"
   );

   // delete show_full_ticket for task
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_full_ticket",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . TicketTask::SEEPUBLIC . " | " .
               TicketTask::SEEPRIVATE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "task"
         ],
         "0.85 update task with show_full_ticket right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_full_ticket"],
      "0.85 delete show_full_ticket right"
   );

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'ticketvalidation']) == 0) {
      // rename delete_validations
      $DB->updateOrDie("glpi_profilerights",
         ['name' => 'ticketvalidation' ],
         ['name' => 'delete_validations'],
         "0.85 rename delete_validations to ticketvalidation"
      );

      $DB->updateOrDie("glpi_profilerights", [
            'rights' => DELETE
         ], [
            'name' => 'ticketvalidation',
            'rights' => 1
         ],
         "0.85 update ticketvalidation with delete_validations right"
      );
   }

   // delete create_request_validation
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "create_request_validation",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . TicketValidation::CREATEREQUEST . " | " .
               PURGE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticketvalidation"
         ],
         "0.85 update ticketvalidation with create_request_validation right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "create_request_validation"],
      "0.85 delete create_request_validation right"
   );

   // delete create_incident_validation
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "create_incident_validation",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . TicketValidation::CREATEINCIDENT . " | " .
               PURGE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticketvalidation"
         ],
         "0.85 update ticketvalidation with create_incident_validation right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "create_incident_validation"],
      "0.85 delete create_incident_validation right"
   );

   // delete validate_request
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "validate_request",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . TicketValidation::VALIDATEREQUEST
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticketvalidation"
         ],
         "0.85 update ticketvalidation with validate_request right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "validate_request"],
      "0.85 delete validate_request right"
   );

   // delete validate_incident
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "validate_incident",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . TicketValidation::VALIDATEINCIDENT
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "ticketvalidation"
         ],
         "0.85 update ticketvalidation with validate_incident right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "validate_incident"],
      "0.85 delete validate_incident right"
   );

   // must be done after ticket right
   // pour que la proc??dure soit r??-entrante
   if (countElementsInTable("glpi_profilerights", ['name' => 'change']) == 0) {
      ProfileRight::addProfileRights(['change']);

      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('change', Change::READMY,
                                                   "`name` = 'ticket'
                                                     AND `rights` & ". Ticket::OWN);
      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('change', Change::READALL,
                                                   "`name` = 'ticket'
                                                     AND `rights` & ".Ticket::READALL);
      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('change',
                                                    CREATE ." | ". UPDATE ." | ". DELETE ." | ". PURGE,
                                                    "`name` = 'ticket' AND `rights` & ".UPDATE);
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'changevalidation']) == 0) {
      ProfileRight::addProfileRights(['changevalidation']);

      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('changevalidation', CREATE,
                                                   "`name` = 'ticketvalidation'
                                                     AND `rights` & ". TicketValidation::CREATEINCIDENT."
                                                     AND `rights` & ". TicketValidation::CREATEREQUEST);
      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('changevalidation', ChangeValidation::VALIDATE,
                                                   "`name` = 'ticketvalidation'
                                                     AND `rights` & ". TicketValidation::VALIDATEINCIDENT."
                                                     AND `rights` & ". TicketValidation::VALIDATEREQUEST);
      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('changevalidation', PURGE,
                                                   "`name` = 'ticketvalidation'
                                                     AND `rights` & ". PURGE);
   }

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'planning']) == 0) {
      // rename show_planning
      $DB->updateOrDie("glpi_profilerights",
         ['name' => "planning"],
         ['name' => "show_planning"],
         "0.85 rename show_planning to planning"
      );

      // READMY = 1 => do update needed
   }

   // delete show_group_planning
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_group_planning",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Planning::READGROUP
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "planning"
         ],
         "0.85 update planning with show_group_planning right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_group_planning"],
      "0.85 delete show_group_planning right"
   );

   // delete show_all_planning
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_all_planning",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Planning::READALL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "planning"
         ],
         "0.85 update planning with show_all_planning right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_all_planning"],
      "0.85 delete show_all_planning right"
   );

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'problem']) == 0) {
      // rename show_my_problem
      $DB->updateOrDie("glpi_profilerights",
         ['name' => "problem"],
         ['name' => "show_my_problem"],
         "0.85 rename show_my_problem to problem"
      );

      // READMY = 1 => do update needed
   }

   // delete show_all_problem
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "show_all_problem",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Problem::READALL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "problem"
         ],
         "0.85 update problem with show_all_problem right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "show_all_problem"],
      "0.85 delete show_all_problem right"
   );

   // delete edit_all_problem
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "edit_all_problem",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . CREATE . " | " . UPDATE . " | " . PURGE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "problem"
         ],
         "0.85 update problem with edit_all_problem right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "edit_all_problem"],
      "0.85 delete edit_all_problem right"
   );

   // delete delete_problem
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "delete_problem",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . DELETE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "problem"
         ],
         "0.85 update problem with delete_problem right"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "delete_problem"],
      "0.85 delete problem right"
   );

   // update search_config
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "search_config",
         'rights' => ALLSTANDARDRIGHT
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . DisplayPreference::PERSONAL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "search_config"
         ],
         "0.85 update search_config with search_config"
      );
   }

   // delete search_config_global
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "search_config_global",
         'rights' => ALLSTANDARDRIGHT
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . DisplayPreference::GENERAL
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "search_config"
         ],
         "0.85 update search_config with search_config_global"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "search_config_global"],
      "0.85 delete search_config_global right"
   );

   // delete check_update
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "check_update",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      $DB->updateOrDie("glpi_profilerights", [
            'rights' => new \QueryExpression(
               $DB->quoteName("rights") . " | " . Backup::CHECKUPDATE
            )
         ], [
            'profiles_id' => $profrights['profiles_id'],
            'name' => "backup"
         ],
         "0.85 update backup with check_update"
      );
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "check_update"],
      "0.85 delete check_update right"
   );

   // entity_dropdown => right by object

   // pour que la proc??dure soit r??-entrante et ne pas perdre les s??lections dans le profile
   if (countElementsInTable("glpi_profilerights", ['name' => 'domain']) == 0) {
      ProfileRight::addProfileRights(['domain']);
      ProfileRight::updateProfileRightsAsOtherRights('domain', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'location']) == 0) {
      ProfileRight::addProfileRights(['location']);
      ProfileRight::updateProfileRightsAsOtherRights('location', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'itilcategory']) == 0) {
      ProfileRight::addProfileRights(['itilcategory']);
      ProfileRight::updateProfileRightsAsOtherRights('itilcategory', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'knowbasecategory']) == 0) {
      ProfileRight::addProfileRights(['knowbasecategory']);
      ProfileRight::updateProfileRightsAsOtherRights('knowbasecategory', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'netpoint']) == 0) {
      ProfileRight::addProfileRights(['netpoint']);
      ProfileRight::updateProfileRightsAsOtherRights('netpoint', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'taskcategory']) == 0) {
      ProfileRight::addProfileRights(['taskcategory']);
      ProfileRight::updateProfileRightsAsOtherRights('taskcategory', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'state']) == 0) {
      ProfileRight::addProfileRights(['state']);
      ProfileRight::updateProfileRightsAsOtherRights('state', 'entity_dropdown');
   }

   if (countElementsInTable("glpi_profilerights", ['name' => 'solutiontemplate']) == 0) {
      ProfileRight::addProfileRights(['solutiontemplate']);
      ProfileRight::updateProfileRightsAsOtherRights('solutiontemplate', 'entity_dropdown');
   }

   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "entity_dropdown"],
      "0.85 delete entity_dropdown right"
   );

   // delete notes
   $tables = ['budget', 'cartridge', 'change','computer', 'consumable', 'contact_enterprise',
                   'contract', 'document', 'entity', 'monitor', 'networking', 'peripheral',
                   'phone', 'printer', 'problem', 'software'];

   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "notes",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      foreach ($tables as $table) {
         $DB->updateOrDie("glpi_profilerights", [
               'rights' => new \QueryExpression(
                  $DB->quoteName("rights") . " | " . READNOTE
               )
            ], [
               'profiles_id' => $profrights['profiles_id'],
               'name' => $table
            ],
            "0.85 update $table with read notes right"
         );
      }
   }
   $profilerightsIterator = $DB->request([
      'FROM'   => "glpi_profilerights",
      'WHERE'  => [
         'name'   => "notes",
         'rights' => 1
      ]
   ]);
   foreach ($profilerightsIterator as $profrights) {
      foreach ($tables as $table) {
         $DB->updateOrDie("glpi_profilerights", [
               'rights' => new \QueryExpression(
                  $DB->quoteName("rights") . " | " . READNOTE . " | " . UPDATENOTE
               )
            ], [
               'profiles_id' => $profrights['profiles_id'],
               'name' => $table
            ],
            "0.85 update $table with update notes right"
         );
      }
   }
   $DB->deleteOrDie("glpi_profilerights",
      ['name' => "notes"],
      "0.85 delete notes right"
   );

   $DELFROMDISPLAYPREF['Profile'] = [29, 35, 37, 43, 53, 54, 57, 65, 66, 67, 68, 69, 70, 71,
                                          72, 73, 74, 75, 76, 77, 78, 80, 81, 88, 93, 94, 95, 96,
                                          97, 98, 99, 104, 113, 114, 116, 117, 121, 122, 123];

   $migration->displayMessage('Update for mailqueue');

   if (!$DB->tableExists('glpi_queuedmails')) {
      $query = "CREATE TABLE `glpi_queuedmails` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `itemtype` varchar(100) default NULL,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  `notificationtemplates_id` int(11) NOT NULL DEFAULT '0',
                  `entities_id` int(11) NOT NULL DEFAULT '0',
                  `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
                  `sent_try` int(11) NOT NULL DEFAULT '0',
                  `create_time` datetime DEFAULT NULL,
                  `send_time` datetime DEFAULT NULL,
                  `sent_time` datetime DEFAULT NULL,
                  `name` TEXT DEFAULT NULL,
                  `sender` TEXT DEFAULT NULL,
                  `sendername` TEXT DEFAULT NULL,
                  `recipient` TEXT DEFAULT NULL,
                  `recipientname` TEXT DEFAULT NULL,
                  `replyto` TEXT DEFAULT NULL,
                  `replytoname` TEXT DEFAULT NULL,
                  `headers` TEXT DEFAULT NULL,
                  `body_html` LONGTEXT DEFAULT NULL,
                  `body_text` LONGTEXT DEFAULT NULL,
                  `messageid` TEXT DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `item` (`itemtype`,`items_id`, `notificationtemplates_id`),
                  KEY `is_deleted` (`is_deleted`),
                  KEY `entities_id` (`entities_id`),
                  KEY `sent_try` (`sent_try`),
                  KEY `create_time` (`create_time`),
                  KEY `send_time` (`send_time`),
                  KEY `sent_time` (`sent_time`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add glpi_queuedmails");
      $ADDTODISPLAYPREF['QueueMail'] = [16, 7, 20, 21, 22, 15];
   }

   if (!countElementsInTable('glpi_crontasks',
                             ['itemtype' => 'QueuedMail', 'name' => 'queuedmail'])) {
      $DB->insertOrDie("glpi_crontasks", [
            'itemtype'        => "QueuedMail",
            'name'            => "queuedmail",
            'frequency'       => 60,
            'param'           => 50,
            'state'           => 1,
            'mode'            => 1,
            'allowmode'       => 3,
            'hourmin'         => 0,
            'hourmax'         => 24,
            'logs_lifetime'   => 30,
            'lastrun'         => null,
            'lastcode'        => null,
            'comment'         => null,
         ],
      "0.85 populate glpi_crontasks for queuemail"
      );
   }

   if (!countElementsInTable('glpi_crontasks',
                             ['itemtype' => 'QueuedMail', 'name' => 'queuedmailclean'])) {
      $DB->insertOrDie("glpi_crontasks", [
            'itemtype'        => "QueuedMail",
            'name'            => "queuedmailclean",
            'frequency'       => 86400,
            'param'           => 30,
            'state'           => 1,
            'mode'            => 1,
            'allowmode'       => 3,
            'hourmin'         => 0,
            'hourmax'         => 24,
            'logs_lifetime'   => 30,
            'lastrun'         => null,
            'lastcode'        => null,
            'comment'         => null,
         ],
         "0.85 populate glpi_crontasks for queuemail"
      );
   }

   if (!countElementsInTable('glpi_crontasks',
                             ['itemtype' => 'Crontask', 'name' => 'temp'])) {
      $DB->insertOrDie("glpi_crontasks", [
            'itemtype'        => "Crontask",
            'name'            => "temp",
            'frequency'       => 3600,
            'param'           => null,
            'state'           => 1,
            'mode'            => 1,
            'allowmode'       => 3,
            'hourmin'         => 0,
            'hourmax'         => 24,
            'logs_lifetime'   => 30,
            'lastrun'         => null,
            'lastcode'        => null,
            'comment'         => null,
         ],
         "0.85 populate glpi_crontasks for clean temporary files"
      );
   }

   if ($migration->addField("glpi_entities", "delay_send_emails", "integer",
                            ['value' => -2])) {
      $migration->migrationOneTable('glpi_entities');
      // Set directly to root entity
      $DB->updateOrDie("glpi_entities",
         ['delay_send_emails' => 0],
         ['id' => 0],
         "0.85 default value for delay_send_emails for root entity"
      );
   }

   // pour que la proc??dure soit r??-entrante
   if (countElementsInTable("glpi_profilerights", ['name' => 'queuedmail']) == 0) {
      ProfileRight::addProfileRights(['queuedmail']);

      ProfileRight::updateProfileRightsAsOtherRights('queuedmail', 'notification');
   }

   $migration->displayMessage(sprintf(__('Change of the database layout - %s'), 'Change'));

   // changes management
   if (!$DB->tableExists('glpi_changes')) {
      $query = "CREATE TABLE `glpi_changes` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) DEFAULT NULL,
                  `entities_id` int(11) NOT NULL DEFAULT '0',
                  `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
                  `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
                  `status` int(11) NOT NULL DEFAULT '1',
                  `content` longtext DEFAULT NULL,
                  `date_mod` DATETIME DEFAULT NULL,
                  `date` DATETIME DEFAULT NULL,
                  `solvedate` DATETIME DEFAULT NULL,
                  `closedate` DATETIME DEFAULT NULL,
                  `due_date` DATETIME DEFAULT NULL,
                  `users_id_recipient` int(11) NOT NULL DEFAULT '0',
                  `users_id_lastupdater` int(11) NOT NULL DEFAULT '0',
                  `urgency` int(11) NOT NULL DEFAULT '1',
                  `impact` int(11) NOT NULL DEFAULT '1',
                  `priority` int(11) NOT NULL DEFAULT '1',
                  `itilcategories_id` int(11) NOT NULL DEFAULT '0',
                  `impactcontent` longtext DEFAULT NULL,
                  `controlistcontent` longtext DEFAULT NULL,
                  `rolloutplancontent` longtext DEFAULT NULL,
                  `backoutplancontent` longtext DEFAULT NULL,
                  `checklistcontent` longtext DEFAULT NULL,
                  `global_validation` varchar(255) COLLATE utf8_unicode_ci DEFAULT 'none',
                  `validation_percent` int(11) NOT NULL DEFAULT '0',
                  `solutiontypes_id` int(11) NOT NULL DEFAULT '0',
                  `solution` text COLLATE utf8_unicode_ci,
                  `actiontime` int(11) NOT NULL DEFAULT '0',
                  `begin_waiting_date` datetime DEFAULT NULL,
                  `waiting_duration` int(11) NOT NULL DEFAULT '0',
                  `close_delay_stat` int(11) NOT NULL DEFAULT '0',
                  `solve_delay_stat` int(11) NOT NULL DEFAULT '0',
                  `notepad` LONGTEXT NULL,
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`),
                  KEY `is_deleted` (`is_deleted`),
                  KEY `date` (`date`),
                  KEY `closedate` (`closedate`),
                  KEY `status` (`status`),
                  KEY `priority` (`priority`),
                  KEY `date_mod` (`date_mod`),
                  KEY `itilcategories_id` (`itilcategories_id`),
                  KEY `users_id_recipient` (`users_id_recipient`),
                  KEY `solvedate` (`solvedate`),
                  KEY `solutiontypes_id` (`solutiontypes_id`),
                  KEY `urgency` (`urgency`),
                  KEY `impact` (`impact`),
                  KEY `due_date` (`due_date`),
                  KEY `global_validation` (`global_validation`),
                  KEY `users_id_lastupdater` (`users_id_lastupdater`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 create glpi_changes");
   }

   $migration->addField('glpi_itilcategories', 'is_change', 'bool', ['value' => 1]);
   $migration->addKey('glpi_itilcategories', 'is_change');

   if (!$DB->tableExists('glpi_changes_users')) {
      $query = "CREATE TABLE `glpi_changes_users` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `users_id` int(11) NOT NULL DEFAULT '0',
                  `type` int(11) NOT NULL DEFAULT '1',
                  `use_notification` tinyint(1) NOT NULL DEFAULT '0',
                  `alternative_email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`type`,`users_id`,`alternative_email`),
                  KEY `user` (`users_id`,`type`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_users");
   }

   if (!$DB->tableExists('glpi_changes_groups')) {
      $query = "CREATE TABLE `glpi_changes_groups` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `groups_id` int(11) NOT NULL DEFAULT '0',
                  `type` int(11) NOT NULL DEFAULT '1',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`type`,`groups_id`),
                  KEY `group` (`groups_id`,`type`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_groups");
   }

   if (!$DB->tableExists('glpi_changes_suppliers')) {
      $query = "CREATE TABLE `glpi_changes_suppliers` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `suppliers_id` int(11) NOT NULL DEFAULT '0',
                  `type` int(11) NOT NULL DEFAULT '1',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`type`,`suppliers_id`),
                  KEY `group` (`suppliers_id`,`type`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_suppliers");
   }

   if (!$DB->tableExists('glpi_changes_items')) {
      $query = "CREATE TABLE `glpi_changes_items` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) default NULL,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`itemtype`,`items_id`),
                  KEY `item` (`itemtype`,`items_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_items");
   }

   if (!$DB->tableExists('glpi_changes_tickets')) {
      $query = "CREATE TABLE `glpi_changes_tickets` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `tickets_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`tickets_id`),
                  KEY `tickets_id` (`tickets_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_tickets");
   }

   if (!$DB->tableExists('glpi_changes_problems')) {
      $query = "CREATE TABLE `glpi_changes_problems` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `problems_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`problems_id`),
                  KEY `problems_id` (`problems_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_problems");
   }

   if (!$DB->tableExists('glpi_changetasks')) {
      $query = "CREATE TABLE `glpi_changetasks` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `taskcategories_id` int(11) NOT NULL DEFAULT '0',
                  `state` int(11) NOT NULL DEFAULT '0',
                  `date` datetime DEFAULT NULL,
                  `begin` datetime DEFAULT NULL,
                  `end` datetime DEFAULT NULL,
                  `users_id` int(11) NOT NULL DEFAULT '0',
                  `users_id_tech` int(11) NOT NULL DEFAULT '0',
                  `content` longtext COLLATE utf8_unicode_ci,
                  `actiontime` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `changes_id` (`changes_id`),
                  KEY `state` (`state`),
                  KEY `users_id` (`users_id`),
                  KEY `users_id_tech` (`users_id_tech`),
                  KEY `date` (`date`),
                  KEY `begin` (`begin`),
                  KEY `end` (`end`),
                  KEY `taskcategories_id` (taskcategories_id)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changetasks");
   }

   if (!$DB->tableExists('glpi_changecosts')) {
      $query = "CREATE TABLE `glpi_changecosts` (
               `id` int(11) NOT NULL AUTO_INCREMENT,
               `changes_id` int(11) NOT NULL DEFAULT '0',
               `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
               `comment` text COLLATE utf8_unicode_ci,
               `begin_date` date DEFAULT NULL,
               `end_date` date DEFAULT NULL,
               `actiontime` int(11) NOT NULL DEFAULT '0',
               `cost_time` decimal(20,4) NOT NULL DEFAULT '0.0000',
               `cost_fixed` decimal(20,4) NOT NULL DEFAULT '0.0000',
               `cost_material` decimal(20,4) NOT NULL DEFAULT '0.0000',
               `budgets_id` int(11) NOT NULL DEFAULT '0',
               `entities_id` int(11) NOT NULL DEFAULT '0',
               `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
               PRIMARY KEY (`id`),
               KEY `name` (`name`),
               KEY `changes_id` (`changes_id`),
               KEY `begin_date` (`begin_date`),
               KEY `end_date` (`end_date`),
               KEY `entities_id` (`entities_id`),
               KEY `is_recursive` (`is_recursive`),
               KEY `budgets_id` (`budgets_id`)
               ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
      $DB->queryOrDie($query, "0.85 add table glpi_changecosts");
   }

   if (!$DB->tableExists('glpi_changevalidations')) {
      $query = "CREATE TABLE `glpi_changevalidations` (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `entities_id` int(11) NOT NULL DEFAULT '0',
            `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
            `users_id` int(11) NOT NULL DEFAULT '0',
            `changes_id` int(11) NOT NULL DEFAULT '0',
            `users_id_validate` int(11) NOT NULL DEFAULT '0',
            `comment_submission` text COLLATE utf8_unicode_ci,
            `comment_validation` text COLLATE utf8_unicode_ci,
            `status` int(11) NOT NULL DEFAULT '2',
            `submission_date` datetime DEFAULT NULL,
            `validation_date` datetime DEFAULT NULL,
            PRIMARY KEY (`id`),
            KEY `entities_id` (`entities_id`),
            KEY `is_recursive` (`is_recursive`),
            KEY `users_id` (`users_id`),
            KEY `users_id_validate` (`users_id_validate`),
            KEY `changes_id` (`changes_id`),
            KEY `submission_date` (`submission_date`),
            KEY `validation_date` (`validation_date`),
            KEY `status` (`status`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
      $DB->queryOrDie($query, "0.85 add table glpi_changevalidations");
   }

   // Change notifications
   $notificationtemplatesIterator = $DB->request('glpi_notificationtemplates', [
      'itemtype' => "Change"
   ]);

   if (count($notificationtemplatesIterator) == 0) {
      $DB->insertOrDie('glpi_notificationtemplates', [
            'name'      => "Changes",
            'itemtype'  => "Change",
            'date_mod'  => new \QueryExpression("NOW()"),
         ],
         "0.85 add change notification"
      );
      $notid = $DB->insertId();

      $contentText = '##IFchange.storestatus=5##
 ##lang.change.url## : ##change.urlapprove##
 ##lang.change.solvedate## : ##change.solvedate##
 ##lang.change.solution.type## : ##change.solution.type##
 ##lang.change.solution.description## : ##change.solution.description## ##ENDIFchange.storestatus##
 ##ELSEchange.storestatus## ##lang.change.url## : ##change.url## ##ENDELSEchange.storestatus##

 ##lang.change.description##

 ##lang.change.title##  :##change.title##
 ##lang.change.authors##  :##IFchange.authors## ##change.authors## ##ENDIFchange.authors## ##ELSEchange.authors##--##ENDELSEchange.authors##
 ##lang.change.creationdate##  :##change.creationdate##
 ##IFchange.assigntousers## ##lang.change.assigntousers##  : ##change.assigntousers## ##ENDIFchange.assigntousers##
 ##lang.change.status##  : ##change.status##
 ##IFchange.assigntogroups## ##lang.change.assigntogroups##  : ##change.assigntogroups## ##ENDIFchange.assigntogroups##
 ##lang.change.urgency##  : ##change.urgency##
 ##lang.change.impact##  : ##change.impact##
 ##lang.change.priority## : ##change.priority##
##IFchange.category## ##lang.change.category##  :##change.category## ##ENDIFchange.category## ##ELSEchange.category## ##lang.change.nocategoryassigned## ##ENDELSEchange.category##
 ##lang.change.content##  : ##change.content##

##IFchange.storestatus=6##
 ##lang.change.solvedate## : ##change.solvedate##
 ##lang.change.solution.type## : ##change.solution.type##
 ##lang.change.solution.description## : ##change.solution.description##
##ENDIFchange.storestatus##
 ##lang.change.numberofproblems## : ##change.numberofproblems##

##FOREACHproblems##
 [##problem.date##] ##lang.change.title## : ##problem.title##
 ##lang.change.content## ##problem.content##

##ENDFOREACHproblems##
 ##lang.change.numberoftasks## : ##change.numberoftasks##

##FOREACHtasks##
 [##task.date##]
 ##lang.task.author## ##task.author##
 ##lang.task.description## ##task.description##
 ##lang.task.time## ##task.time##
 ##lang.task.category## ##task.category##

##ENDFOREACHtasks##
';

      $contentHtml = '&lt;p&gt;##IFchange.storestatus=5##&lt;/p&gt;
&lt;div&gt;##lang.change.url## : &lt;a href=\"##change.urlapprove##\"&gt;##change.urlapprove##&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=\"color: #888888;\"&gt;&lt;strong&gt;&lt;span style=\"text-decoration: underline;\"&gt;##lang.change.solvedate##&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt; : ##change.solvedate##&lt;br /&gt;&lt;span style=\"text-decoration: underline; color: #888888;\"&gt;&lt;strong&gt;##lang.change.solution.type##&lt;/strong&gt;&lt;/span&gt; : ##change.solution.type##&lt;br /&gt;&lt;span style=\"text-decoration: underline; color: #888888;\"&gt;&lt;strong&gt;##lang.change.solution.description##&lt;/strong&gt;&lt;/span&gt; : ##change.solution.description## ##ENDIFchange.storestatus##&lt;/div&gt;
&lt;div&gt;##ELSEchange.storestatus## ##lang.change.url## : &lt;a href=\"##change.url##\"&gt;##change.url##&lt;/a&gt; ##ENDELSEchange.storestatus##&lt;/div&gt;
&lt;p class=\"description b\"&gt;&lt;strong&gt;##lang.change.description##&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.title##&lt;/span&gt;&#160;:##change.title## &lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.authors##&lt;/span&gt;&#160;:##IFchange.authors## ##change.authors## ##ENDIFchange.authors##    ##ELSEchange.authors##--##ENDELSEchange.authors## &lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.creationdate##&lt;/span&gt;&#160;:##change.creationdate## &lt;br /&gt; ##IFchange.assigntousers## &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.assigntousers##&lt;/span&gt;&#160;: ##change.assigntousers## ##ENDIFchange.assigntousers##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt;##lang.change.status## &lt;/span&gt;&#160;: ##change.status##&lt;br /&gt; ##IFchange.assigntogroups## &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.assigntogroups##&lt;/span&gt;&#160;: ##change.assigntogroups## ##ENDIFchange.assigntogroups##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.urgency##&lt;/span&gt;&#160;: ##change.urgency##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.impact##&lt;/span&gt;&#160;: ##change.impact##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.priority##&lt;/span&gt; : ##change.priority## &lt;br /&gt;##IFchange.category##&lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt;##lang.change.category## &lt;/span&gt;&#160;:##change.category##  ##ENDIFchange.category## ##ELSEchange.category##  ##lang.change.nocategoryassigned## ##ENDELSEchange.category##    &lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.change.content##&lt;/span&gt;&#160;: ##change.content##&lt;/p&gt;
&lt;p&gt;##IFchange.storestatus=6##&lt;br /&gt;&lt;span style=\"text-decoration: underline;\"&gt;&lt;strong&gt;&lt;span style=\"color: #888888;\"&gt;##lang.change.solvedate##&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt; : ##change.solvedate##&lt;br /&gt;&lt;span style=\"color: #888888;\"&gt;&lt;strong&gt;&lt;span style=\"text-decoration: underline;\"&gt;##lang.change.solution.type##&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt; : ##change.solution.type##&lt;br /&gt;&lt;span style=\"text-decoration: underline; color: #888888;\"&gt;&lt;strong&gt;##lang.change.solution.description##&lt;/strong&gt;&lt;/span&gt; : ##change.solution.description##&lt;br /&gt;##ENDIFchange.storestatus##&lt;/p&gt;
&lt;div class=\"description b\"&gt;##lang.change.numberofproblems##&#160;: ##change.numberofproblems##&lt;/div&gt;
&lt;p&gt;##FOREACHproblems##&lt;/p&gt;
&lt;div&gt;&lt;strong&gt; [##problem.date##] &lt;em&gt;##lang.change.title## : &lt;a href=\"##problem.url##\"&gt;##problem.title## &lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; &lt;/span&gt;&lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt;##lang.change.content## &lt;/span&gt; ##problem.content##
&lt;p&gt;##ENDFOREACHproblems##&lt;/p&gt;
&lt;div class=\"description b\"&gt;##lang.change.numberoftasks##&#160;: ##change.numberoftasks##&lt;/div&gt;
&lt;p&gt;##FOREACHtasks##&lt;/p&gt;
&lt;div class=\"description b\"&gt;&lt;strong&gt;[##task.date##] &lt;/strong&gt;&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.task.author##&lt;/span&gt; ##task.author##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.task.description##&lt;/span&gt; ##task.description##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.task.time##&lt;/span&gt; ##task.time##&lt;br /&gt; &lt;span style=\"color: #8b8c8f; font-weight: bold; text-decoration: underline;\"&gt; ##lang.task.category##&lt;/span&gt; ##task.category##&lt;/div&gt;
&lt;p&gt;##ENDFOREACHtasks##&lt;/p&gt;
&lt;/div&gt;';

      $DB->insertOrDie("glpi_notificationtemplatetranslations", [
            'notificationtemplates_id' => $notid,
            'language'     => "",
            'subject'      => "##change.action## ##change.title##",
            'content_text' => $contentText,
            'content_html' => $contentHtml
         ],
         "0.85 add change notification translation"
      );

      $notifications = ['new'         => [],
                             'update'      => [Notification::ASSIGN_TECH,
                                                    Notification::OLD_TECH_IN_CHARGE],
                             'solved'      => [],
                             'add_task'    => [],
                             'update_task' => [],
                             'delete_task' => [],
                             'closed'      => [],
                             'delete'      => []];

      $notif_names   = ['new'         => 'New Change',
                             'update'      => 'Update Change',
                             'solved'      => 'Resolve Change',
                             'add_task'    => 'Add Task',
                             'update_task' => 'Update Task',
                             'delete_task' => 'Delete Task',
                             'closed'      => 'Close Change',
                             'delete'      => 'Delete Change'];

      foreach ($notifications as $key => $val) {
         $notifications[$key][] = Notification::AUTHOR;
         $notifications[$key][] = Notification::GLOBAL_ADMINISTRATOR;
         $notifications[$key][] = Notification::OBSERVER;
      }

      foreach ($notifications as $type => $targets) {
         $DB->insertOrDie("glpi_notifications", [
               'name'                     => $notif_names[$type],
               'entities_id'              => 0,
               'itemtype'                 => "Change",
               'event'                    => $type,
               'mode'                     => "mail",
               'notificationtemplates_id' => $notid,
               'comment'                  => "",
               'is_recursive'             => 1,
               'is_active'                => 1,
               'date_mod'                 => new \QueryExpression("NOW()")
            ],
            "0.85 add change $type notification"
         );
         $notifid = $DB->insertId();

         foreach ($targets as $target) {
            $DB->insertOrDie("glpi_notificationtargets", [
                  'id'                 => null,
                  'notifications_id'   => $notifid,
                  'type'               => Notification::USER_TYPE,
                  'items_id'           => $target,
               ],
               "0.85 add change $type notification target"
            );
         }
      }
   }

   $ADDTODISPLAYPREF['Change'] = [12,19,15,7,18];

   $migration->addField('glpi_profiles', 'change_status', "text",
                        ['comment' => "json encoded array of from/dest allowed status change"]);

   // Add problem costs
   if (!$DB->tableExists('glpi_problemcosts')) {
      $query = "CREATE TABLE `glpi_problemcosts` (
               `id` int(11) NOT NULL AUTO_INCREMENT,
               `problems_id` int(11) NOT NULL DEFAULT '0',
               `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
               `comment` text COLLATE utf8_unicode_ci,
               `begin_date` date DEFAULT NULL,
               `end_date` date DEFAULT NULL,
               `actiontime` int(11) NOT NULL DEFAULT '0',
               `cost_time` decimal(20,4) NOT NULL DEFAULT '0.0000',
               `cost_fixed` decimal(20,4) NOT NULL DEFAULT '0.0000',
               `cost_material` decimal(20,4) NOT NULL DEFAULT '0.0000',
               `budgets_id` int(11) NOT NULL DEFAULT '0',
               `entities_id` int(11) NOT NULL DEFAULT '0',
               PRIMARY KEY (`id`),
               KEY `name` (`name`),
               KEY `problems_id` (`problems_id`),
               KEY `begin_date` (`begin_date`),
               KEY `end_date` (`end_date`),
               KEY `entities_id` (`entities_id`),
               KEY `budgets_id` (`budgets_id`)
               ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
      $DB->queryOrDie($query, "0.85 add table glpi_problemcosts");
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'drop rules cache'));

   $migration->dropTable('glpi_rulecachecomputermodels');
   $migration->dropTable('glpi_rulecachecomputertypes');
   $migration->dropTable('glpi_rulecachemanufacturers');
   $migration->dropTable('glpi_rulecachemonitormodels');
   $migration->dropTable('glpi_rulecachemonitortypes');
   $migration->dropTable('glpi_rulecachenetworkequipmentmodels');
   $migration->dropTable('glpi_rulecachenetworkequipmenttypes');
   $migration->dropTable('glpi_rulecacheoperatingsystems');
   $migration->dropTable('glpi_rulecacheoperatingsystemservicepacks');
   $migration->dropTable('glpi_rulecacheoperatingsystemversions');
   $migration->dropTable('glpi_rulecacheperipheralmodels');
   $migration->dropTable('glpi_rulecacheperipheraltypes');
   $migration->dropTable('glpi_rulecachephonemodels');
   $migration->dropTable('glpi_rulecachephonetypes');
   $migration->dropTable('glpi_rulecacheprintermodels');
   $migration->dropTable('glpi_rulecacheprinters');
   $migration->dropTable('glpi_rulecacheprintertypes');
   $migration->dropTable('glpi_rulecachesoftwares');

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_rules'));

   $migration->addField("glpi_rules", 'uuid', "string");
   $migration->addField("glpi_slalevels", 'uuid', "string");
   $migration->migrationOneTable('glpi_rules');
   $migration->migrationOneTable('glpi_slalevels');

   // Dropdown translations
   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_knowbaseitemtranslations'));

   Config::setConfigurationValues('core', ['translate_kb' => 0]);
   if (!$DB->tableExists("glpi_knowbaseitemtranslations")) {
      $query = "CREATE TABLE IF NOT EXISTS `glpi_knowbaseitemtranslations` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `knowbaseitems_id` int(11) NOT NULL DEFAULT '0',
                  `language` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `name` text COLLATE utf8_unicode_ci,
                  `answer` longtext COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `item` (`knowbaseitems_id`, `language`),
                  FULLTEXT KEY `fulltext` (`name`,`answer`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
      $DB->queryOrDie($query, "0.85 add table glpi_knowbaseitemtranslations");
   }

   // kb translations
   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_dropdowntranslations'));

   Config::setConfigurationValues('core', ['translate_dropdowns' => 0]);
   if (!$DB->tableExists("glpi_dropdowntranslations")) {
      $query = "CREATE TABLE IF NOT EXISTS `glpi_dropdowntranslations` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `language` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `field` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `value` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`itemtype`,`items_id`,`language`,`field`),
                  KEY `typeid` (`itemtype`,`items_id`),
                  KEY `language` (`language`),
                  KEY `field` (`field`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";

      $DB->queryOrDie($query, "0.85 add table glpi_dropdowntranslations");
   }

   //generate uuid for the basic rules of glpi
   // we use a complete sql where for cover all migration case (0.78 -> 0.85)
   $rules = [['sub_type'    => 'RuleImportEntity',
                        'name'        => 'Root',
                        'match'       => 'AND',
                        'description' => ''],

                  ['sub_type'    => 'RuleRight',
                        'name'        => 'Root',
                        'match'       => 'AND',
                        'description' => ''],

                  ['sub_type'    => 'RuleMailCollector',
                        'name'        => 'Root',
                        'match'       => 'AND',
                        'description' => ''],

                  ['sub_type'    => 'RuleMailCollector',
                        'name'        => 'Auto-Reply X-Auto-Response-Suppress',
                        'match'       => 'AND',
                        'description' => 'Exclude Auto-Reply emails using X-Auto-Response-Suppress header'],

                  ['sub_type'    => 'RuleMailCollector',
                        'name'        => 'Auto-Reply Auto-Submitted',
                        'match'       => 'AND',
                        'description' => 'Exclude Auto-Reply emails using Auto-Submitted header'],

                  ['sub_type'    => 'RuleTicket',
                        'name'        => 'Ticket location from item',
                        'match'       => 'AND',
                        'description' => ''],

                  ['sub_type'    => 'RuleTicket',
                        'name'        => 'Ticket location from user',
                        'match'       => 'AND',
                        'description' => '']];

   $i = 0;
   foreach ($rules as $rule) {
      $DB->updateOrDie("glpi_rules", [
            'uuid' => "STATIC-UUID-$i"
         ], [
            'WHERE' => [
               'entities_id'  => 0,
               'is_recursive' => 0,
               'sub_type'     => $rule['sub_type'],
               'name'         => $rule['name'],
               'description'  => $rule['description'],
               'match'        => $rule['match'],
            ],
            "ORDER" => ['id ASC'],
            "LIMIT" => 1,
         ],
         "0.85 add uuid to basic rules (STATIC-UUID-$i)"
      );
      $i++;
   }

   //generate uuid for the rules of user
   foreach ($DB->request('glpi_rules', ['uuid' => null]) as $data) {
      $DB->updateOrDie("glpi_rules",
         ['uuid' => Rule::getUuid()],
         ['id' => $data['id']],
         "0.85 add uuid to existing rules"
      );
   }

   foreach ($DB->request('glpi_slalevels', ['uuid' => null]) as $data) {
      $DB->updateOrDie("glpi_slalevels",
         ['uuid' => Rule::getUuid()],
         ['id' => $data['id']],
         "0.85 add uuid to existing slalevels"
      );
   }

   $migration->addField('glpi_users', 'is_deleted_ldap', 'bool');
   $migration->addKey('glpi_users', 'is_deleted_ldap');

   Config::deleteConfigurationValues('core', ['use_ajax']);
   Config::deleteConfigurationValues('core', ['ajax_min_textsearch_load']);
   Config::deleteConfigurationValues('core', ['ajax_buffertime_load']);

   Config::deleteConfigurationValues('core', ['is_categorized_soft_expanded']);
   Config::deleteConfigurationValues('core', ['is_not_categorized_soft_expanded']);
   $migration->dropField("glpi_users", 'is_categorized_soft_expanded');
   $migration->dropField("glpi_users", 'is_not_categorized_soft_expanded');

   // Config::setConfigurationValues('core', array('use_unicodefont' => 0));
   // $migration->addField("glpi_users", 'use_unicodefont', "int(11) DEFAULT NULL");
   Config::deleteConfigurationValues('core', ['use_unicodefont']);
   $migration->dropField("glpi_users", 'use_unicodefont');
   Config::setConfigurationValues('core', ['pdffont' => 'helvetica']);
   $migration->addField("glpi_users", 'pdffont', "string");

   $migration->addField("glpi_users", 'picture', "string");

   $migration->addField("glpi_authldaps", 'picture_field', 'string');

   $migration->addField('glpi_links', 'open_window', 'bool', ['value' => 1]);

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_states'));

   foreach (['is_visible_computer', 'is_visible_monitor', 'is_visible_networkequipment',
                  'is_visible_peripheral', 'is_visible_phone', 'is_visible_printer',
                  'is_visible_softwareversion'] as $field) {
      $migration->addField('glpi_states', $field, 'bool',
                           ['value' => '1']);
      $migration->addKey('glpi_states', $field);
   }

   // glpi_domains by entity
   $migration->addField('glpi_domains', 'entities_id', 'integer', ['after' => 'name']);
   $migration->addField('glpi_domains', 'is_recursive', 'bool', ['update' => '1',
                                                                      'after'  => 'entities_id']);

   // glpi_states by entity
   $migration->addField('glpi_states', 'entities_id', 'integer', ['after' => 'name']);
   $migration->addField('glpi_states', 'is_recursive', 'bool', ['update' => '1',
                                                                     'after'  => 'entities_id']);

   // add validity date for a user
   $migration->addField('glpi_users', 'begin_date', 'datetime');
   $migration->addField('glpi_users', 'end_date', 'datetime');

   // add validity date for a knowbaseitem
   $migration->addField('glpi_knowbaseitems', 'begin_date', 'datetime');
   $migration->addField('glpi_knowbaseitems', 'end_date', 'datetime');

   // Add validation percent for tickets
   $migration->addField('glpi_tickets', 'validation_percent', 'integer', ['value' => 0]);

   // Add missing key
   $migration->addKey('glpi_tickettasks', 'state');
   $migration->addKey('glpi_tickettasks', 'users_id_tech');
   $migration->addKey('glpi_tickettasks', 'begin');
   $migration->addKey('glpi_tickettasks', 'end');

   // Create notification for reply to satisfaction survey based on satisfaction notif
   // Check if notifications already exists
   if (countElementsInTable('glpi_notifications',
                            ['itemtype' => 'Ticket',
                             'event'    => 'replysatisfaction'])==0) {
      // No notifications duplicate all

      $notificationsIterator = $DB->request("glpi_notifications", [
         'itemtype'  => "Ticket",
         'event'     => "satisfaction",
      ]);

      foreach ($notificationsIterator as $notif) {
         $DB->insertOrDie("glpi_notifications", [
               'name'                     => $notif['name']. "Answer",
               'entities_id'              => $notif['entities_id'],
               'itemtype'                 => 'Ticket',
               'event'                    => "replysatisfaction",
               'mode'                     => $notif['mode'],
               'notificationtemplates_id' => $notif['notificationtemplates_id'],
               'comment'                  => $notif['comment'],
               'is_recursive'             => $notif['is_recursive'],
               'is_active'                => $notif['is_active'],
               'date_mod'                 => new \QueryExpression("NOW()")
            ],
            "0.85 insert replysatisfaction notification"
         );
         $newID  = $DB->insertId();
         $notificationtargetsIterator = $DB->request("glpi_notificationtargets", [
            'notifications_id' => $notif['id']
         ]);
         // Add same recipent of satisfaction
         foreach ($notificationtargetsIterator as $target) {
            $DB->insertOrDie("glpi_notificationtargets", [
                  'notifications_id'   => $newID,
                  'type'               => $target['type'],
                  'items_id'           => $target['items_id'],
               ],
               "0.85 insert targets for replysatisfaction notification"
            );
         }
         // Add Tech in charge
         $DB->insertOrDie("glpi_notificationtargets", [
               'notifications_id'   => $newID,
               'type'               => Notification::USER_TYPE,
               'items_id'           => Notification::ASSIGN_TECH
            ],
            "0.85 insert tech in charge target for replysatisfaction notification"
         );
      }
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_slas'));

   // * Convert SLA resolution time to new system (ticket #4346)
   if (!$DB->fieldExists("glpi_slas", "definition_time")) {
      $migration->addField("glpi_slas", 'definition_time', "string");
      $migration->addField("glpi_slas", 'end_of_working_day', "bool");
      $migration->migrationOneTable('glpi_slas');

      // Minutes
      $slasIterator = $DB->request("glpi_slas", [
         'resolution_time' => ["<=", 3000]
      ]);
      if (count($slasIterator)) {
         $a_ids = [];
         while ($data = $slasIterator->next()) {
            $a_ids[] = $data['id'];
         }
         $DB->update("glpi_slas", [
               'definition_time' => "minute",
               'resolution_time' => new \QueryExpression(
                  $DB->quoteName("resolution_time") . "/60"
               )
            ], [
               'id' => $a_ids
            ]
         );
      }
      // Hours
      $slasIterator = $DB->request("glpi_slas", [
         'resolution_time' => [">", 3000],
         'resolution_time' => ["<=", 82800]
      ]);
      if (count($slasIterator)) {
         $a_ids = [];
         while ($data = $slasIterator->next()) {
            $a_ids[] = $data['id'];
         }
         $DB->update("glpi_slas", [
               'definition_time' => "hour",
               'resolution_time' => new \QueryExpression(
                  $DB->quoteName("resolution_time") . "/3600"
               )
            ], [
               'id' => $a_ids
            ]
         );
      }
      // Days
      $slasIterator = $DB->request("glpi_slas", [
         'resolution_time' => [">", 82800]
      ]);
      if (count($slasIterator)) {
         $a_ids = [];
         while ($data = $slasIterator->next()) {
            $a_ids[] = $data['id'];
         }
         $DB->update("glpi_slas", [
               'definition_time' => "day",
               'resolution_time' => new \QueryExpression(
                  $DB->quoteName("resolution_time") . "/86400"
               )
            ], [
               'id' => $a_ids
            ]
         );
      }
   }

   Config::setConfigurationValues('core', ['keep_devices_when_purging_item' => 0]);
   $migration->addField("glpi_users", "keep_devices_when_purging_item", "int(11) DEFAULT NULL");

   Config::setConfigurationValues('core', ['maintenance_mode' => 0]);
   Config::setConfigurationValues('core', ['maintenance_text' => '']);

   $notificationtemplatesIterator = $DB->request("glpi_notificationtemplates", [
      'itemtype' => "MailCollector"
   ]);

   if (count($notificationtemplatesIterator) == 0) {
      $DB->insertOrDie("glpi_notificationtemplates", [
            'name'      => "Receiver errors",
            'itemtype'  => "MailCollector",
            'date_mod'  => new \QueryExpression("NOW()"),
         ],
         "0.85 add mail collector notification"
      );
      $notid = $DB->insertId();

      $contentText = '##FOREACHmailcollectors##
##lang.mailcollector.name## : ##mailcollector.name##
##lang.mailcollector.errors## : ##mailcollector.errors##
##mailcollector.url##
##ENDFOREACHmailcollectors##';

      $contentHtml = '&lt;p&gt;##FOREACHmailcollectors##&lt;br /&gt;##lang.mailcollector.name## : ##mailcollector.name##&lt;br /&gt; ##lang.mailcollector.errors## : ##mailcollector.errors##&lt;br /&gt;&lt;a href=\"##mailcollector.url##\"&gt;##mailcollector.url##&lt;/a&gt;&lt;br /&gt; ##ENDFOREACHmailcollectors##&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;';

      $DB->insertOrDie("glpi_notificationtemplatetranslations", [
            'notificationtemplates_id' => $notid,
            'language' => "",
            'subject' => '##mailcollector.action##',
            'content_text' => $contentText,
            'content_html' => $contentHtml,
         ],
         "0.85 add mail collector notification translation"
      );

      $DB->insertOrDie("glpi_notifications", [
            'name'                     => "Receiver errors",
            'entities_id'              => 0,
            'itemtype'                 => "MailCollector",
            'event'                    => "error",
            'mode'                     => "mail",
            'notificationtemplates_id' => $notid,
            'comment'                  => "",
            'is_recursive'             => 1,
            'is_active'                => 1,
            'date_mod'                 => new \QueryExpression("NOW()")
         ],
         "0.85 add mail collector notification"
      );
      $notifid = $DB->insertId();

      $DB->insertOrDie("glpi_notificationtargets", [
            'id'                 => null,
            'notifications_id'   => $notifid,
            'type'               => Notification::USER_TYPE,
            'items_id'           => Notification::GLOBAL_ADMINISTRATOR
         ],
         "0.85 add mail collector notification target"
      );
   }

   if (!countElementsInTable('glpi_crontasks',
                             ['itemtype' => 'MailCollector', 'name' => 'mailgateerror'])) {
      $DB->insertOrDie("glpi_crontasks", [
            'itemtype'        => "MailCollector",
            'name'            => "mailgateerror",
            'frequency'       => DAY_TIMESTAMP,
            'param'           => null,
            'state'           => 1,
            'mode'            => 1,
            'allowmode'       => 3,
            'hourmin'         => 0,
            'hourmax'         => 24,
            'logs_lifetime'   => 30,
            'lastrun'         => null,
            'lastcode'        => null,
            'comment'         => null,
         ],
         "0.85 populate glpi_crontasks for mailgateerror"
      );
   }
   if (!countElementsInTable('glpi_crontasks',
                             ['itemtype' => 'Crontask', 'name' => 'circularlogs'])) {
      $DB->insertOrDie("glpi_crontasks", [
            'itemtype'        => "Crontask",
            'name'            => "circularlogs",
            'frequency'       => DAY_TIMESTAMP,
            'param'           => 4,
            'state'           => CronTask::STATE_DISABLE,
            'mode'            => 1,
            'allowmode'       => 3,
            'hourmin'         => 0,
            'hourmax'         => 24,
            'logs_lifetime'   => 30,
            'lastrun'         => null,
            'lastcode'        => null,
            'comment'         => null,
         ],
         "0.85 populate glpi_crontasks for circularlogs"
      );
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_documents'));

   $migration->addField('glpi_documents', 'is_blacklisted', 'bool');

   if (!$DB->tableExists("glpi_blacklistedmailcontents")) {
      $query = "CREATE TABLE IF NOT EXISTS `glpi_blacklistedmailcontents` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) DEFAULT NULL,
                  `content` text COLLATE utf8_unicode_ci,
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";
      $DB->queryOrDie($query, "0.85 add table glpi_blacklistedmailcontents");
   }

   $migration->addField('glpi_documents', 'tag', 'string');
   $migration->addField('glpi_queuedmails', 'documents', 'text');
   $migration->addKey('glpi_documents', 'tag');
   Config::setConfigurationValues('core', ['use_rich_text' => 0]);
   Config::setConfigurationValues('core', ['attach_ticket_documents_to_mail' => 0]);

   $migration->migrationOneTable('glpi_documents');
   $DB->updateOrDie('glpi_documents',
      ['tag' => new QueryExpression($DB->quoteName("id"))],
      [true],
      "0.85 set tag to all documents"
   );

   // increase password length
   $migration->changeField('glpi_users', 'password', 'password', 'string');

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_softwarecategories'));

   // Hierarchical software category
   $migration->addField('glpi_softwarecategories', 'softwarecategories_id', 'integer');
   $migration->addField("glpi_softwarecategories", 'completename', "text");
   $migration->addField("glpi_softwarecategories", 'level', "integer");
   $migration->addField("glpi_softwarecategories", 'ancestors_cache', "longtext");
   $migration->addField("glpi_softwarecategories", 'sons_cache', "longtext");
   $migration->migrationOneTable('glpi_softwarecategories');
   $migration->addKey('glpi_softwarecategories', 'softwarecategories_id');
   regenerateTreeCompleteName("glpi_softwarecategories");

   $migration->displayMessage(sprintf(__('Change of the database layout - %s'), 'various'));

   // glpi_cartridgeitems  glpi_consumableitems by entity
   $migration->addField('glpi_consumableitems', 'is_recursive', 'bool',
                         ['update' => '1',
                               'after'  => 'entities_id']);
   $migration->addField('glpi_cartridgeitems', 'is_recursive', 'bool',
                        ['update' => '1',
                              'after'  => 'entities_id']);
   // Fix events
   $DB->updateOrDie("glpi_events",
      ['type' => "consumableitems"],
      ['type' => "consumables"],
      "0.85 fix events for consumables"
   );

   $DB->updateOrDie("glpi_events",
      ['type' => "cartridgeitems"],
      ['type' => "cartridges"],
      "0.85 fix events for cartridges"
   );
   // Bookmark order :
   $migration->addField('glpi_users', 'privatebookmarkorder', 'longtext');

   // Pref to comme back ticket created
   if ($migration->addField('glpi_users', 'backcreated', 'TINYINT(1) DEFAULT NULL')) {
      $DB->insertOrDie("glpi_configs", [
            'context'   => "core",
            'name'      => "backcreated",
            'value'     => 0
         ],
         "update glpi_configs with backcreated"
      );
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_projects'));

   if (!$DB->tableExists("glpi_projects")) {
      $query = "CREATE TABLE IF NOT EXISTS `glpi_projects` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `priority` int(11) NOT NULL DEFAULT '1',
                  `entities_id` int(11) NOT NULL DEFAULT '0',
                  `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
                  `projects_id` int(11) NOT NULL DEFAULT '0',
                  `projectstates_id` int(11) NOT NULL DEFAULT '0',
                  `projecttypes_id` int(11) NOT NULL DEFAULT '0',
                  `date` datetime DEFAULT NULL,
                  `date_mod` datetime DEFAULT NULL,
                  `users_id` int(11) NOT NULL DEFAULT '0',
                  `groups_id` int(11) NOT NULL DEFAULT '0',
                  `plan_start_date` datetime DEFAULT NULL,
                  `plan_end_date` datetime DEFAULT NULL,
                  `real_start_date` datetime DEFAULT NULL,
                  `real_end_date` datetime DEFAULT NULL,
                  `percent_done` int(11) NOT NULL DEFAULT '0',
                  `show_on_global_gantt` tinyint(1) NOT NULL DEFAULT '0',
                  `content` longtext DEFAULT NULL,
                  `comment` longtext DEFAULT NULL,
                  `notepad` longtext DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `code` (`code`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`),
                  KEY `projects_id` (`projects_id`),
                  KEY `projectstates_id` (`projectstates_id`),
                  KEY `projecttypes_id` (`projecttypes_id`),
                  KEY `priority` (`priority`),
                  KEY `date` (`date`),
                  KEY `date_mod` (`date_mod`),
                  KEY `users_id` (`users_id`),
                  KEY `groups_id` (`groups_id`),
                  KEY `plan_start_date` (`plan_start_date`),
                  KEY `plan_end_date` (`plan_end_date`),
                  KEY `real_start_date` (`real_start_date`),
                  KEY `real_end_date` (`real_end_date`),
                  KEY `percent_done` (`percent_done`),
                  KEY `show_on_global_gantt` (`show_on_global_gantt`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";

      $DB->queryOrDie($query, "0.85 add table glpi_projects");
      $ADDTODISPLAYPREF['Project'] = [3,4,12,5,15,21];
   }

   $migration->addField("glpi_projects", 'is_deleted', "bool");

   if (countElementsInTable("glpi_profilerights", ['name' => 'project']) == 0) {
      ProfileRight::addProfileRights(['project']);

      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('project', Project::READMY,
                                                   "`name` = 'change'
                                                     AND `rights` & ". Change::READMY);

      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('project', Project::READALL,
                                                   "`name` = 'change'
                                                     AND `rights` & ".Change::READALL);

      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('project',
                                                    CREATE ." | ". UPDATE ." | ". DELETE ." | ". PURGE ." | ".READNOTE ." | ".UPDATENOTE,
                                                    "`name` = 'change'
                                                      AND `rights` & (".CREATE ." | ". UPDATE ." | ". DELETE ." | ". PURGE.')');
   }
   if (countElementsInTable("glpi_profilerights", ['name' => 'projecttask']) == 0) {
      ProfileRight::addProfileRights(['projecttask']);

      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('projecttask', ProjectTask::READMY,
                                                   "`name` = 'change'
                                                     AND `rights` & ". Change::READMY);
      // TODO : to improve when updateProfileRightAsOtherRight support the new request structure
      ProfileRight::updateProfileRightAsOtherRight('projecttask', ProjectTask::UPDATEMY,
                                                   "`name` = 'change'
                                                     AND `rights` & ".Change::READMY);
   }

   if (!$DB->tableExists('glpi_projectcosts')) {
      $query = "CREATE TABLE `glpi_projectcosts` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `projects_id` int(11) NOT NULL DEFAULT '0',
                  `name` varchar(255) DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  `begin_date` date DEFAULT NULL,
                  `end_date` date DEFAULT NULL,
                  `cost` decimal(20,4) NOT NULL DEFAULT '0.0000',
                  `budgets_id` int(11) NOT NULL DEFAULT '0',
                  `entities_id` int(11) NOT NULL DEFAULT '0',
                  `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `projects_id` (`projects_id`),
                  KEY `begin_date` (`begin_date`),
                  KEY `end_date` (`end_date`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`),
                  KEY `budgets_id` (`budgets_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_projectcosts");
   }

   if (!$DB->tableExists('glpi_projectstates')) {
      $query = "CREATE TABLE `glpi_projectstates` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  `color` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `is_finished` tinyint(1) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `is_finished` (`is_finished`)
                ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 create glpi_projectstates");

      $ADDTODISPLAYPREF['ProjectState'] = [12,11];
      $states = ['new' => ['name'        => _x('ticket', 'New'),
                                     'color'       => '#06ff00',
                                     'is_finished' => 0],
                      'do'  => ['name'        => __('Processing'),
                                     'color'       => '#ffb800',
                                     'is_finished' => 0],
                      'end' => ['name'        => __('Closed'),
                                     'color'       => '#ff0000',
                                     'is_finished' => 1]];
      foreach ($states as $key => $val) {
         $DB->insertOrDie("glpi_projectstates", [
               'name'         => $val['name'],
               'color'        => $val['color'],
               'is_finished'  => $val['is_finished']
            ],
            "0.85 insert default project state $key"
         );
      }
   }
   if (!$DB->tableExists('glpi_projecttypes')) {
      $query = "CREATE TABLE `glpi_projecttypes` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`)
                ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 create glpi_projecttypes");
   }
   $migration->addField("glpi_groups", 'is_manager', "bool", ['update' => "`is_assign`",
                                                                   'value'  => 1]);
   $migration->addKey('glpi_groups', 'is_manager');

   if (!$DB->tableExists('glpi_changes_projects')) {
      $query = "CREATE TABLE `glpi_changes_projects` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `changes_id` int(11) NOT NULL DEFAULT '0',
                  `projects_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`changes_id`,`projects_id`),
                  KEY `projects_id` (`projects_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_changes_projects");
   }

   if (!$DB->tableExists('glpi_projectteams')) {
      $query = "CREATE TABLE `glpi_projectteams` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `projects_id` int(11) NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) default NULL,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`projects_id`,`itemtype`,`items_id`),
                  KEY `item` (`itemtype`,`items_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_projectteams");
   }

   if (!$DB->tableExists('glpi_items_projects')) {
      $query = "CREATE TABLE `glpi_items_projects` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `projects_id` int(11) NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) default NULL,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`projects_id`,`itemtype`,`items_id`),
                  KEY `item` (`itemtype`,`items_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_items_projects");
   }

   if (!$DB->tableExists("glpi_projecttasks")) {
      $query = "CREATE TABLE IF NOT EXISTS `glpi_projecttasks` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `content` longtext DEFAULT NULL,
                  `comment` longtext DEFAULT NULL,
                  `entities_id` int(11) NOT NULL DEFAULT '0',
                  `is_recursive` tinyint(1) NOT NULL DEFAULT '0',
                  `projects_id` int(11) NOT NULL DEFAULT '0',
                  `projecttasks_id` int(11) NOT NULL DEFAULT '0',
                  `date` datetime DEFAULT NULL,
                  `date_mod` datetime DEFAULT NULL,
                  `plan_start_date` datetime DEFAULT NULL,
                  `plan_end_date` datetime DEFAULT NULL,
                  `real_start_date` datetime DEFAULT NULL,
                  `real_end_date` datetime DEFAULT NULL,
                  `planned_duration` int(11) NOT NULL DEFAULT '0',
                  `effective_duration` int(11) NOT NULL DEFAULT '0',
                  `projectstates_id` int(11) NOT NULL DEFAULT '0',
                  `projecttasktypes_id` int(11) NOT NULL DEFAULT '0',
                  `users_id` int(11) NOT NULL DEFAULT '0',
                  `percent_done` int(11) NOT NULL DEFAULT '0',
                  `notepad` longtext DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`),
                  KEY `entities_id` (`entities_id`),
                  KEY `is_recursive` (`is_recursive`),
                  KEY `projects_id` (`projects_id`),
                  KEY `projecttasks_id` (`projecttasks_id`),
                  KEY `date` (`date`),
                  KEY `date_mod` (`date_mod`),
                  KEY `users_id` (`users_id`),
                  KEY `plan_start_date` (`plan_start_date`),
                  KEY `plan_end_date` (`plan_end_date`),
                  KEY `real_start_date` (`real_start_date`),
                  KEY `real_end_date` (`real_end_date`),
                  KEY `percent_done` (`percent_done`),
                  KEY `projectstates_id` (`projectstates_id`),
                  KEY `projecttasktypes_id` (`projecttasktypes_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;";

      $DB->queryOrDie($query, "0.85 add table glpi_projecttasks");
      $ADDTODISPLAYPREF['ProjectTask'] = [2,12,14,5,7,8, 13];
   }
   if (!$DB->tableExists('glpi_projecttasktypes')) {
      $query = "CREATE TABLE `glpi_projecttasktypes` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
                  `comment` text COLLATE utf8_unicode_ci,
                  PRIMARY KEY (`id`),
                  KEY `name` (`name`)
                ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 create glpi_projecttasktypes");
   }
   if (!$DB->tableExists('glpi_projecttaskteams')) {
      $query = "CREATE TABLE `glpi_projecttaskteams` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `projecttasks_id` int(11) NOT NULL DEFAULT '0',
                  `itemtype` varchar(100) default NULL,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`projecttasks_id`,`itemtype`,`items_id`),
                  KEY `item` (`itemtype`,`items_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_projecttaskteams");
   }

   if (!$DB->tableExists('glpi_projecttasks_tickets')) {
      $query = "CREATE TABLE `glpi_projecttasks_tickets` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `tickets_id` int(11) NOT NULL DEFAULT '0',
                  `projecttasks_id` int(11) NOT NULL DEFAULT '0',
                  PRIMARY KEY (`id`),
                  UNIQUE KEY `unicity` (`tickets_id`,`projecttasks_id`),
                  KEY `projects_id` (`projecttasks_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_projecttasks_tickets");
   }

   // Project notifications
   $notificationtemplatesIterator = $DB->request("glpi_notificationtemplates", [
      'itemtype' => "Project"
   ]);

   if (count($notificationtemplatesIterator) == 0) {
      $DB->insertOrDie("glpi_notificationtemplates", [
            'name'      => "Projects",
            'itemtype'  => "Project",
            'date_mod'  => new \QueryExpression("NOW()")
         ],
         "0.85 add project notification"
      );
      $notid = $DB->insertId();

      $contentText = '##lang.project.url## : ##project.url##

##lang.project.description##

##lang.project.name## : ##project.name##
##lang.project.code## : ##project.code##
##lang.project.manager## : ##project.manager##
##lang.project.managergroup## : ##project.managergroup##
##lang.project.creationdate## : ##project.creationdate##
##lang.project.priority## : ##project.priority##
##lang.project.state## : ##project.state##
##lang.project.type## : ##project.type##
##lang.project.description## : ##project.description##

##lang.project.numberoftasks## : ##project.numberoftasks##



##FOREACHtasks##

[##task.creationdate##]
##lang.task.name## : ##task.name##
##lang.task.state## : ##task.state##
##lang.task.type## : ##task.type##
##lang.task.percent## : ##task.percent##
##lang.task.description## : ##task.description##

##ENDFOREACHtasks##';

      $contentHtml = '&lt;p&gt;##lang.project.url## : &lt;a href=\"##project.url##\"&gt;##project.url##&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;##lang.project.description##&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;##lang.project.name## : ##project.name##&lt;br /&gt;##lang.project.code## : ##project.code##&lt;br /&gt; ##lang.project.manager## : ##project.manager##&lt;br /&gt;##lang.project.managergroup## : ##project.managergroup##&lt;br /&gt; ##lang.project.creationdate## : ##project.creationdate##&lt;br /&gt;##lang.project.priority## : ##project.priority## &lt;br /&gt;##lang.project.state## : ##project.state##&lt;br /&gt;##lang.project.type## : ##project.type##&lt;br /&gt;##lang.project.description## : ##project.description##&lt;/p&gt;
&lt;p&gt;##lang.project.numberoftasks## : ##project.numberoftasks##&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;##FOREACHtasks##&lt;/p&gt;
&lt;div&gt;&lt;strong&gt;[##task.creationdate##] &lt;/strong&gt;&lt;br /&gt; ##lang.task.name## : ##task.name##&lt;br /&gt;##lang.task.state## : ##task.state##&lt;br /&gt;##lang.task.type## : ##task.type##&lt;br /&gt;##lang.task.percent## : ##task.percent##&lt;br /&gt;##lang.task.description## : ##task.description##&lt;/div&gt;
&lt;p&gt;##ENDFOREACHtasks##&lt;/p&gt;
&lt;/div&gt;';

      $DB->insertOrDie("glpi_notificationtemplatetranslations", [
            'notificationtemplates_id' => $notid,
            'language'                 => "",
            'subject'                  => "##project.action## ##project.name## ##project.code##",
            'content_text'             => $contentText,
            'content_html'             => $contentHtml
         ],
         "0.85 add project notification translation"
      );

      $notifications = ['new'         => [],
                             'update'      => [],
                             'delete'      => []];

      $notif_names   = ['new'         => 'New Project',
                             'update'      => 'Update Project',
                             'delete'      => 'Delete Project'];

      foreach ($notifications as $key => $val) {
         $notifications[$key][] = Notification::MANAGER_USER;
         $notifications[$key][] = Notification::GLOBAL_ADMINISTRATOR;
         $notifications[$key][] = Notification::MANAGER_GROUP;
      }

      foreach ($notifications as $type => $targets) {
         $DB->insertOrDie("glpi_notifications", [
               'name'                     => $notif_names[$type],
               'entities_id'              => 0,
               'itemtype'                 => "Project",
               'event'                    => $type,
               'mode'                     => "mail",
               'notificationtemplates_id' => $notid,
               'comment'                  => "",
               'is_recursive'             => 1,
               'is_active'                => 1,
               'date_mod'                 => new \QueryExpression("NOW()"),
            ],
            "0.85 add project $type notification"
         );
         $notifid = $DB->insertId();

         foreach ($targets as $target) {
            $DB->insertOrDie("glpi_notificationtargets", [
                  'id'                 => null,
                  'notifications_id'   => $notifid,
                  'type'               =>  Notification::USER_TYPE,
                  'items_id'           => $target
               ],
               "0.85 add project $type notification target"
            );
         }
      }
   }

   // Project Task notifications
   $notificationtemplatesIterator = $DB->request("glpi_notificationtemplates", [
      'itemtype' => "ProjectTask"
   ]);

   if (count($notificationtemplatesIterator) == 0) {
      $DB->insertOrDie("glpi_notificationtemplates", [
            'name'      => "Project Tasks",
            'itemtype'  => "ProjectTask",
            'date_mod'  => new \QueryExpression("NOW()")
         ],
         "0.85 add project notification"
      );
      $notid = $DB->insertId();

      $contentText = '##lang.projecttask.url## : ##projecttask.url##

##lang.projecttask.description##

##lang.projecttask.name## : ##projecttask.name##
##lang.projecttask.project## : ##projecttask.project##
##lang.projecttask.creationdate## : ##projecttask.creationdate##
##lang.projecttask.state## : ##projecttask.state##
##lang.projecttask.type## : ##projecttask.type##
##lang.projecttask.description## : ##projecttask.description##

##lang.projecttask.numberoftasks## : ##projecttask.numberoftasks##



##FOREACHtasks##

[##task.creationdate##]
##lang.task.name## : ##task.name##
##lang.task.state## : ##task.state##
##lang.task.type## : ##task.type##
##lang.task.percent## : ##task.percent##
##lang.task.description## : ##task.description##

##ENDFOREACHtasks##';
      $contentHtml = '&lt;p&gt;##lang.projecttask.url## : &lt;a href=\"##projecttask.url##\"&gt;##projecttask.url##&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;##lang.projecttask.description##&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;##lang.projecttask.name## : ##projecttask.name##&lt;br /&gt;##lang.projecttask.project## : &lt;a href=\"##projecttask.projecturl##\"&gt;##projecttask.project##&lt;/a&gt;&lt;br /&gt;##lang.projecttask.creationdate## : ##projecttask.creationdate##&lt;br /&gt;##lang.projecttask.state## : ##projecttask.state##&lt;br /&gt;##lang.projecttask.type## : ##projecttask.type##&lt;br /&gt;##lang.projecttask.description## : ##projecttask.description##&lt;/p&gt;
&lt;p&gt;##lang.projecttask.numberoftasks## : ##projecttask.numberoftasks##&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;##FOREACHtasks##&lt;/p&gt;
&lt;div&gt;&lt;strong&gt;[##task.creationdate##] &lt;/strong&gt;&lt;br /&gt;##lang.task.name## : ##task.name##&lt;br /&gt;##lang.task.state## : ##task.state##&lt;br /&gt;##lang.task.type## : ##task.type##&lt;br /&gt;##lang.task.percent## : ##task.percent##&lt;br /&gt;##lang.task.description## : ##task.description##&lt;/div&gt;
&lt;p&gt;##ENDFOREACHtasks##&lt;/p&gt;
&lt;/div&gt;';
      $DB->insertOrDie("glpi_notificationtemplatetranslations", [
            'notificationtemplates_id' => $notid,
            'language'                 => "",
            'subject'                  => "##projecttask.action## ##projecttask.name##",
            'content_text'             => $contentText,
            'content_html'             => $contentHtml
         ],
         "0.85 add project task notification translation"
      );

      $notifications = ['new'         => [],
                             'update'      => [],
                             'delete'      => []];

      $notif_names   = ['new'         => 'New Project Task',
                             'update'      => 'Update Project Task',
                             'delete'      => 'Delete Project Task'];

      foreach ($notifications as $key => $val) {
         $notifications[$key][] = Notification::TEAM_USER;
         $notifications[$key][] = Notification::GLOBAL_ADMINISTRATOR;
         $notifications[$key][] = Notification::TEAM_GROUP;
      }

      foreach ($notifications as $type => $targets) {
         $DB->insertOrDie("glpi_notifications", [
               'name'                     => $notif_names[$type],
               'entities_id'              => 0,
               'itemtype'                 => "ProjectTask",
               'event'                    => $type,
               'mode'                     => "mail",
               'notificationtemplates_id' => $notid,
               'comment'                  => "",
               'is_recursive'             => 1,
               'is_active'                => 1,
               'date_mod'                 => new \QueryExpression("NOW()")
            ],
            "0.85 add project task  $type notification"
         );
         $notifid = $DB->insertId();

         foreach ($targets as $target) {
            $DB->insertOrDie("glpi_notificationtargets", [
                  'id'                 => null,
                  'notifications_id'   => $notifid,
                  'type'               => Notification::USER_TYPE,
                  'items_id'           => $target
               ],
               "0.85 add project task $type notification target"
            );
         }
      }
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'notepad'));
   // Create new notepad table
   if (!$DB->tableExists('glpi_notepads')) {
      $query = "CREATE TABLE `glpi_notepads` (
                  `id` int(11) NOT NULL AUTO_INCREMENT,
                  `itemtype` varchar(100) default NULL,
                  `items_id` int(11) NOT NULL DEFAULT '0',
                  `date` datetime DEFAULT NULL,
                  `date_mod` datetime DEFAULT NULL,
                  `users_id` int(11) NOT NULL DEFAULT '0',
                  `users_id_lastupdater` int(11) NOT NULL DEFAULT '0',
                  `content` LONGTEXT DEFAULT NULL,
                  PRIMARY KEY (`id`),
                  KEY `item` (`itemtype`,`items_id`),
                  KEY `date_mod` (`date_mod`),
                  KEY `date` (`date`),
                  KEY `users_id_lastupdater` (`users_id_lastupdater`),
                  KEY `users_id` (`users_id`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_notepads");

      $notepad_tables = ['glpi_budgets', 'glpi_cartridgeitems', 'glpi_changes',
                              'glpi_computers', 'glpi_consumableitems', 'glpi_contacts',
                              'glpi_contracts', 'glpi_documents', 'glpi_entities',
                              'glpi_monitors', 'glpi_networkequipments', 'glpi_peripherals',
                              'glpi_phones', 'glpi_printers', 'glpi_problems', 'glpi_projects',
                              'glpi_projecttasks', 'glpi_softwares', 'glpi_suppliers'];

      foreach ($notepad_tables as $t) {
         // Migrate data
         if ($DB->fieldExists($t, 'notepad', false)) {
            $notepadIterator = $DB->request([
               'SELECT' => ["id", "notepad"],
               'FROM'   => $t,
               'WHERE'  => [
                  new \QueryExpression($DB->quoteName("notepad") . " IS NOT NULL"),
                  ["notepad" => ["<>", ""]]
               ]
            ]);
            foreach ($notepadIterator as $data) {
               $DB->insertOrDie("glpi_notepads", [
                     'itemtype'  => getItemTypeForTable($t),
                     'items_id'  => $data['id'],
                     'content'   => $data['notepad'],
                     'date'      => new \QueryExpression("NOW()"),
                     'date_mod'  => new \QueryExpression("NOW()")
                  ],
                  "0.85 migrate notepad data"
               );
            }
            $migration->dropField($t, 'notepad');
         }
      }
   }

   $migration->addField('glpi_deviceprocessors', 'nbcores_default', 'int');
   $migration->addField('glpi_deviceprocessors', 'nbthreads_default', 'int');

   $migration->addField('glpi_items_deviceprocessors', 'nbcores', 'int');
   $migration->addField('glpi_items_deviceprocessors', 'nbthreads', 'int');
   $migration->addKey('glpi_items_deviceprocessors', 'nbcores');
   $migration->addKey('glpi_items_deviceprocessors', 'nbthreads');

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'ticketvalidations status'));

   $status  = ['none'     => CommonITILValidation::NONE,
                    'waiting'  => CommonITILValidation::WAITING,
                    'accepted' => CommonITILValidation::ACCEPTED,
                    'rejected' => CommonITILValidation::REFUSED];

   // Migrate datas
   foreach ($status as $old => $new) {
      $DB->updateOrDie("glpi_ticketvalidations",
         ['status' => $new],
         ['status' => $old],
         "0.85 status in glpi_ticketvalidations $old to $new"
      );
   }

   $migration->changeField('glpi_ticketvalidations', 'status', 'status', 'integer',
                           ['value' => CommonITILValidation::WAITING]);

   $migration->displayMessage(sprintf(__('Data migration - %s'),
                              'tickets and changes global_validation'));

   $tables = ['glpi_tickets', 'glpi_changes'];
   foreach ($tables as $table) {
      foreach ($status as $old => $new) {
         $DB->updateOrDie($table,
            ['global_validation' => $new],
            ['global_validation' => $old],
            "0.85 global_validation in $table $old to $new"
         );
      }
      $migration->changeField($table, 'global_validation', 'global_validation', 'integer',
                              ['value' => CommonITILValidation::NONE]);
   }

   $migration->displayMessage(sprintf(__('Data migration - %s'),
                                      'tickettemplatepredefinedfields value'));

   foreach ($status as $old => $new) {
      $DB->updateOrDie("glpi_tickettemplatepredefinedfields", [
            'value' => $new
         ], [
            'num'    => 52,
            'value'  => $old
         ],
         "0.85 value in glpi_tickettemplatepredefinedfields $old to $new"
      );
   }

   // Migrate templates
   $templateIterator = $DB->request([
      'SELECT'       => "glpi_notificationtemplatetranslations.*",
      'FROM'         => "glpi_notificationtemplatetranslations",
      'INNER JOIN'   => [
         'glpi_notificationtemplates' => [
            'ON' => [
               'glpi_notificationtemplates' => "id",
               'glpi_notificationtemplatetranslations' => "notificationtemplates_id"
            ]
         ]
      ],
      'WHERE'        => [
         'OR' => [
            "glpi_notificationtemplatetranslations.content_text" => [
               "LIKE", "%validation.storestatus=%"
            ],
            "glpi_notificationtemplatetranslations.content_html" => [
               "LIKE", "%validation.storestatus=%"
            ],
            "glpi_notificationtemplatetranslations.subject" => ["LIKE", "%validation.storestatus=%"]
         ]
      ]
   ]);

   if (count($templateIterator)) {
      while ($data = $templateIterator->next()) {
         $subject = $data['subject'];
         $text    = $data['content_text'];
         $html    = $data['content_html'];
         foreach ($status as $old => $new) {
            $subject = str_replace("validation.storestatus=$old", "validation.storestatus=$new",
                                   $subject);
            $text    = str_replace("validation.storestatus=$old", "validation.storestatus=$new",
                                   $text);
            $html    = str_replace("validation.storestatus=$old", "validation.storestatus=$new",
                                   $html);
         }
         $DB->updateOrDie("glpi_notificationtemplatetranslations", [
               'subject'      => $subject,
               'content_text' => $text,
               'content_html' => $html
            ], [
               'id' => $data['id']
            ],
            "0.85 fix tags usage for storestatus"
         );
      }
   }

   // Upgrade ticket bookmarks
   $bookmarksIterator = $DB->request("glpi_bookmarks");

   if (count($bookmarksIterator)) {
      while ($data = $bookmarksIterator->next()) {
         $options = [];
         parse_str($data["query"], $options);
         if (isset($options['field'])) {
            // update ticket statuses
            if (($data['itemtype'] = 'Ticket')
                &&( $data['type'] == Bookmark::SEARCH)) {
               foreach ($options['field'] as $key => $val) {
                  if ((($val == 55) || ($val == 52))
                      && isset($options['contains'][$key])) {
                     if (isset($status[$options['contains'][$key]])) {
                        $options['contains'][$key] = $status[$options['contains'][$key]];
                     }
                  }
               }
            }
         }
         $DB->updateOrDie("glpi_bookmarks",
            ['query' => Toolbox::append_params($options)],
            ['id' => $data['id']],
            "0.85 update bookmarks"
         );
      }
   }

   //////////////////////////////////////////////////
   // Device update
   $migration->displayMessage(sprintf(__('Data migration - %s'), 'Devices'));

   $devices = [
      'DeviceMotherboard',
      'DeviceProcessor',
      'DeviceMemory',
      'DeviceHardDrive',
      'DeviceNetworkCard',
      'DeviceDrive',
      'DeviceControl',
      'DeviceGraphicCard',
      'DeviceSoundCard',
      'DevicePci',
      'DeviceCase',
      'DevicePowerSupply',
      'Item_DeviceMotherboard',
      'Item_DeviceProcessor',
      'Item_DeviceMemory',
      'Item_DeviceHardDrive',
      'Item_DeviceNetworkCard',
      'Item_DeviceDrive',
      'Item_DeviceControl',
      'Item_DeviceGraphicCard',
      'Item_DeviceSoundCard',
      'Item_DevicePci',
      'Item_DeviceCase',
      'Item_DevicePowerSupply'
   ];

   foreach ($devices as $itemtype) {
      $table = $itemtype::getTable();
      if (!$DB->fieldExists($table, 'entities_id')) {
         $migration->addField($table, 'entities_id', 'integer');
         $migration->addKey($table, ['entities_id'], 'entities_id');
      }
      if (!$DB->fieldExists($table, 'is_recursive')) {
         $migration->addField($table, 'is_recursive', 'bool', ['update' => '1',
                                                                    'after'  => 'entities_id']);
         $migration->addKey($table, ['is_recursive'], 'is_recursive');
      }

   }

   // Adding the Registered ID class that contains PCI IDs and USB IDs for vendors
   // as well devices
   if (!$DB->tableExists('glpi_registeredids')) {
      $query = "CREATE TABLE `glpi_registeredids` (
                 `id` int(11) NOT NULL AUTO_INCREMENT,
                 `name` varchar(255) DEFAULT NULL,
                 `items_id` int(11) NOT NULL DEFAULT '0',
                 `itemtype` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
                 `device_type` varchar(100) COLLATE utf8_unicode_ci NOT NULL COMMENT 'USB, PCI ...',
                 PRIMARY KEY (`id`),
                 KEY `name` (`name`),
                 KEY `item` (`items_id`, `itemtype`),
                 KEY `device_type` (`device_type`)
               ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci";
      $DB->queryOrDie($query, "0.85 add table glpi_registeredids");
   }

   // Complete the item_devices
   foreach (['glpi_items_devicecases', 'glpi_items_devicecontrols', 'glpi_items_devicedrives',
                  'glpi_items_devicegraphiccards', 'glpi_items_devicemotherboards',
                  'glpi_items_devicenetworkcards', 'glpi_items_devicepcis',
                  'glpi_items_devicepowersupplies', 'glpi_items_devicesoundcards'] as $table) {
      if (!$DB->fieldExists($table, 'serial')) {
         $migration->addField($table, 'serial', 'string');
         $migration->addKey($table, 'serial');
      }
   }

   foreach (['glpi_items_devicecontrols', 'glpi_items_devicedrives',
                  'glpi_items_devicegraphiccards', 'glpi_items_deviceharddrives',
                  'glpi_items_devicememories', 'glpi_items_devicenetworkcards',
                  'glpi_items_devicepcis', 'glpi_items_deviceprocessors',
                  'glpi_items_devicesoundcards'] as $table) {
      if (!$DB->fieldExists($table, 'busID')) {
         $migration->addField($table, 'busID', 'string');
         $migration->addKey($table, 'busID');
      }
   }

   // Add key
   foreach (['glpi_items_devicecases', 'glpi_items_devicecontrols', 'glpi_items_devicedrives',
                  'glpi_items_devicegraphiccards', 'glpi_items_deviceharddrives',
                  'glpi_items_devicememories', 'glpi_items_devicemotherboards',
                  'glpi_items_devicenetworkcards', 'glpi_items_devicepcis',
                  'glpi_items_devicepowersupplies', 'glpi_items_deviceprocessors',
                  'glpi_items_devicesoundcards'] as $table) {
      $migration->dropKey($table, 'item');
      $migration->migrationOneTable($table);
      $migration->addKey($table, ['itemtype', 'items_id'], 'item');
   }

   if (!$DB->fieldExists('glpi_devicegraphiccards', 'chipset')) {
      $migration->addField('glpi_devicegraphiccards', 'chipset', 'string');
      $migration->addKey('glpi_devicegraphiccards', 'chipset');
   }

   $migration->addField("glpi_suppliers_tickets", "use_notification", "bool");
   $migration->addField("glpi_suppliers_tickets", "alternative_email", "string");
   $migration->addField("glpi_problems_suppliers", "use_notification", "bool");
   $migration->addField("glpi_problems_suppliers", "alternative_email", "string");
   $migration->addField("glpi_changes_suppliers", "use_notification", "bool");
   $migration->addField("glpi_changes_suppliers", "alternative_email", "string");

   // Add field for locations
   $migration->addField("glpi_locations", "latitude", "string");
   $migration->addField("glpi_locations", "longitude", "string");
   $migration->addField("glpi_locations", "altitude", "string");

   // Add fixed columns as variables :
   $ADDTODISPLAYPREF['CartridgeItem']   = [9];
   $ADDTODISPLAYPREF['ConsumableItem']  = [9];
   $ADDTODISPLAYPREF['ReservationItem'] = [9];

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'License validity'));
   // for licence validity
   if ($migration->addField("glpi_softwarelicenses", "is_valid", "bool", ["value" => 1])) {
      $migration->migrationOneTable("glpi_softwarelicenses");

      // Force all entities
      if (!isset($_SESSION['glpishowallentities'])) {
         $_SESSION['glpishowallentities'] = 0;
      }
      $savesession = $_SESSION['glpishowallentities'];
      $_SESSION['glpishowallentities'] = 1;

      $softwarelicenseIterator = $DB->request([
         'SELECT' => ["id", "number"],
         'FROM'   => "glpi_softwarelicenses"
      ]);

      foreach ($softwarelicenseIterator AS $datal) {
         if (($datal['number'] >= 0)
             && ($datal['number'] < Computer_SoftwareLicense::countForLicense($datal['id'], -1))) {

            $DB->updateOrDie("glpi_softwarelicenses",
               ['is_valid' => 0],
               ['id' => $datal['id']],
               "0.85 update softwarelicense"
            );
         }
      }
      $_SESSION['glpishowallentities'] = $savesession;
   }

   if ($migration->addField("glpi_softwares", "is_valid", "bool", ["value" => 1])) {
      $migration->migrationOneTable("glpi_softwares");

      $softwareIterator = $DB->request([
         'SELECT'    => "glpi_softwares.id",
         'FROM'      => "glpi_softwares",
         'LEFT JOIN' => [
            'glpi_softwarelicenses' => [
               'ON' => [
                  'glpi_softwarelicenses' => "softwares_id",
                  'glpi_softwares'        => "id"
               ]
            ]
         ],
         'WHERE'     => ['glpi_softwarelicenses.is_valid' => 0]
      ]);

      foreach ($softwareIterator AS $datas) {
         $DB->updateOrDie("glpi_softwares",
            ['is_valid' => 0],
            ['id' => $datas['id']],
            "0.85 update software"
         );
      }
   }

   // Add condition to rules
   $migration->addField('glpi_rules', 'condition', 'integer');
   $migration->addKey('glpi_rules', 'condition');
   $migration->migrationOneTable('glpi_rules');

   // Update condition for RuleTicket : only on add
   $DB->updateOrDie("glpi_rules",
      ['condition' => 1],
      ['sub_type' => "RuleTicket"],
      "0.85 update condition for RuleTicket"
   );

   // Update ticket_status for helpdeks profiles
   $newcycle =  [ 1 =>  [ 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, ],
                       2 =>  [ 1 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, ],
                       3 =>  [ 1 => 0, 2 => 0, 4 => 0, 5 => 0, 6 => 0, ],
                       4 =>  [ 1 => 0, 2 => 0, 3 => 0, 5 => 0, 6 => 0, ],
                       5 =>  [ 1 => 0, 2 => 0, 3 => 0, 4 => 0, ],
                       6 =>  [ 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, ], ];
   $DB->updateOrDie("glpi_profiles",
      ['ticket_status' => exportArrayToDB($newcycle)],
      ['interface' => "helpdesk"],
      "0.85 update default life cycle for helpdesk"
   );
   //Add comment field to a virtualmachine
   $migration->addField('glpi_computervirtualmachines', 'comment', 'text');

   $migration->displayMessage(sprintf(__('Data migration - %s'), 'IP improvment'));
   // Ip search improve
   $migration->addField('glpi_ipaddresses', 'mainitems_id', 'integer');
   $migration->addField('glpi_ipaddresses', 'mainitemtype', 'string', ['after'  => 'mainitems_id']);
   $migration->migrationOneTable('glpi_ipaddresses');
   $migration->addKey('glpi_ipaddresses', ['mainitemtype', 'mainitems_id', 'is_deleted'], 'mainitem');

   // TODO : can be improved when DBmysql->updateOrDie() supports join statement
   $query_doc_i = "UPDATE `glpi_ipaddresses` as `ip`
                   INNER JOIN `glpi_networknames` as `netname`
                     ON  (`ip`.`items_id` = `netname`.`id`
                            AND `ip`.`itemtype` = 'NetworkName')
                   INNER JOIN `glpi_networkports` as `netport`
                     ON  (`netname`.`items_id` = `netport`.`id`
                            AND `netname`.`itemtype` = 'NetworkPort')
                   SET `ip`.`mainitemtype` = `netport`.`itemtype`,
                       `ip`.`mainitems_id` = `netport`.`items_id`";
   $DB->queryOrDie($query_doc_i, "0.85 update mainitems fields of ipaddresses");

   // Upgrade ticket bookmarks
   $bookmarksIterator = $DB->request([
      'FROM'   => "glpi_bookmarks",
      'WHERE'  => ['type' => Bookmark::SEARCH]
   ]);

   if (count($bookmarksIterator)) {
      while ($data = $bookmarksIterator->next()) {
         $options = [];
         parse_str($data["query"], $options);

         // Copy itemtype if not set
         if (!isset($options['itemtype'])) {
            $options['itemtype'] = $data['itemtype'];
         }
         // Move criteria
         if (isset($options['field']) && is_array($options['field'])) {
            $newkey = 0;
            foreach ($options['field'] as $key => $val) {
               $options['criteria'][$newkey]['field'] = $val;

               //  other field
               if (isset($options['link'][$key])) {
                  $options['criteria'][$newkey]['link'] = $options['link'][$key];
               }

               if (isset($options['searchtype'][$key])) {
                  $options['criteria'][$newkey]['searchtype'] = $options['searchtype'][$key];
               } else {
                  $options['criteria'][$newkey]['searchtype'] = 'contains';
               }

               if (isset($options['contains'][$key])) {
                  $options['criteria'][$newkey]['value'] = $options['contains'][$key];
               } else {
                  $options['criteria'][$newkey]['value'] = '';
               }
               $newkey++;
            }
            unset($options['field']);
            unset($options['contains']);
            unset($options['searchtype']);
            unset($options['link']);
         }
         if (isset($options['glpisearchcount'])) {
            unset($options['glpisearchcount']);
         }

         if (isset($options['field2']) && is_array($options['field2'])) {
            $newkey = 0;
            foreach ($options['field2'] as $key => $val) {
               $options['metacriteria'][$newkey]['field'] = $val;

               //  other field
               if (isset($options['itemtype2'][$key])) {
                  $options['metacriteria'][$newkey]['itemtype'] = $options['itemtype2'][$key];
               }

               if (isset($options['link2'][$newkey])) {
                  $options['metacriteria'][$newkey]['link'] = $options['link2'][$key];
               }

               if (isset($options['searchtype2'][$key])) {
                  $options['metacriteria'][$newkey]['searchtype'] = $options['searchtype2'][$key];
               } else {
                  $options['metacriteria'][$newkey]['searchtype'] = 'contains';
               }

               if (isset($options['contains2'][$key])) {
                  $options['metacriteria'][$newkey]['value'] = $options['contains2'][$key];
               } else {
                  $options['metacriteria'][$newkey]['value'] = '';
               }
               $newkey++;
            }
            unset($options['field2']);
            unset($options['contains2']);
            unset($options['searchtype2']);
            unset($options['link2']);
            unset($options['itemtype2']);
         }
         if (isset($options['glpisearchcount2'])) {
            unset($options['glpisearchcount2']);
         }

         $DB->updateOrDie("glpi_bookmarks",
            ['query' => Toolbox::append_params($options)],
            ['id' => $data['id']],
            "0.85 update bookmarks for reorg search"
         );
      }
   }
   // ************ Keep it at the end **************
   //TRANS: %s is the table or item to migrate
   $migration->displayMessage(sprintf(__('Data migration - %s'), 'glpi_displaypreferences'));

   // Clean display prefs
   // Notepad
   $DB->update("glpi_displaypreferences", [
         'num' => 90
      ], [
         'itemtype'  => 'Entity',
         'num'       => 28
      ]
   );
   $DB->update("glpi_displaypreferences",
      ['num' => 200],
      ['num' => 90]
   );
   $migration->updateDisplayPrefs($ADDTODISPLAYPREF, $DELFROMDISPLAYPREF);

   // must always be at the end
   $migration->executeMigration();

   return $updateresult;
}

require_once __DIR__ .'/old_objects.php';
